diff --git a/analysis/Manifest.toml b/analysis/Manifest.toml index 3748887..aa1e0d7 100644 --- a/analysis/Manifest.toml +++ b/analysis/Manifest.toml @@ -1190,7 +1190,7 @@ version = "0.4.3" [[deps.ReCo]] deps = ["CellListMap", "Dates", "Distributions", "Flux", "Intervals", "JLD2", "LaTeXStrings", "LinearAlgebra", "ProgressMeter", "Random", "ReinforcementLearning", "StaticArrays", "UnicodePlots"] -git-tree-sha1 = "7b7f1cf73718423fa293397ce7796055549a0686" +git-tree-sha1 = "50559f3f3d0a26055675cd78776b8bafe1bada3a" repo-rev = "main" repo-url = ".." uuid = "b25f7548-fcc9-4c91-bc24-841b54f4dd54" diff --git a/graphics/CairoMakie_graphics/Manifest.toml b/graphics/CairoMakie_graphics/Manifest.toml index 06b17af..22831ed 100644 --- a/graphics/CairoMakie_graphics/Manifest.toml +++ b/graphics/CairoMakie_graphics/Manifest.toml @@ -1149,7 +1149,7 @@ version = "0.4.3" [[deps.ReCo]] deps = ["CellListMap", "Dates", "Distributions", "Flux", "Intervals", "JLD2", "LaTeXStrings", "LinearAlgebra", "ProgressMeter", "Random", "ReinforcementLearning", "StaticArrays", "UnicodePlots"] -git-tree-sha1 = "7b7f1cf73718423fa293397ce7796055549a0686" +git-tree-sha1 = "50559f3f3d0a26055675cd78776b8bafe1bada3a" repo-rev = "main" repo-url = "../.." uuid = "b25f7548-fcc9-4c91-bc24-841b54f4dd54" diff --git a/graphics/Luxor_graphics/Manifest.toml b/graphics/Luxor_graphics/Manifest.toml index 6da8ac4..698778a 100644 --- a/graphics/Luxor_graphics/Manifest.toml +++ b/graphics/Luxor_graphics/Manifest.toml @@ -944,7 +944,7 @@ version = "1.5.3" [[deps.ReCo]] deps = ["CellListMap", "Dates", "Distributions", "Flux", "Intervals", "JLD2", "LaTeXStrings", "LinearAlgebra", "ProgressMeter", "Random", "ReinforcementLearning", "StaticArrays", "UnicodePlots"] -git-tree-sha1 = "7b7f1cf73718423fa293397ce7796055549a0686" +git-tree-sha1 = "50559f3f3d0a26055675cd78776b8bafe1bada3a" repo-rev = "main" repo-url = "../.." uuid = "b25f7548-fcc9-4c91-bc24-841b54f4dd54" diff --git a/performance/Manifest.toml b/performance/Manifest.toml index d1b19d0..9188eab 100644 --- a/performance/Manifest.toml +++ b/performance/Manifest.toml @@ -978,7 +978,7 @@ version = "1.5.3" [[deps.ReCo]] deps = ["CellListMap", "Dates", "Distributions", "Flux", "Intervals", "JLD2", "LaTeXStrings", "LinearAlgebra", "ProgressMeter", "Random", "ReinforcementLearning", "StaticArrays", "UnicodePlots"] -git-tree-sha1 = "7b7f1cf73718423fa293397ce7796055549a0686" +git-tree-sha1 = "50559f3f3d0a26055675cd78776b8bafe1bada3a" repo-rev = "main" repo-url = ".." uuid = "b25f7548-fcc9-4c91-bc24-841b54f4dd54" diff --git a/visualization/Animation.jl b/visualization/Animation.jl index 8bf0869..8b6c7c7 100644 --- a/visualization/Animation.jl +++ b/visualization/Animation.jl @@ -2,10 +2,11 @@ module Animation export animate -using GLMakie using ColorSchemes: ColorSchemes -using LaTeXStrings: @L_str +using GLMakie using JLD2: JLD2 +using LaTeXStrings: @L_str +using Observables: Observables using ProgressMeter: ProgressMeter using ReCo: ReCo @@ -19,130 +20,143 @@ const DEFAULT_SHOW_SKIN_CIRCLE = false const DEFAULT_SHOW_FRAME_DIFF = false const DEFAULT_SHOW_PROGRESS = false -function animate_bundle!(args, sim_consts::ReCo.SimConsts) - bundle_t = args.bundle.t - bundle_c = args.bundle.c - bundle_φ = args.bundle.φ +function update_values!( + args, sim_consts::ReCo.SimConsts, bundle::ReCo.Bundle, bundle_snapshot::Integer +) + @simd for particle_ind in 1:(sim_consts.n_particles) + c = bundle.c[particle_ind, bundle_snapshot] + φ = bundle.φ[particle_ind, bundle_snapshot] - for bundle_snapshot in 1:length(bundle_t) - @simd for particle_ind in 1:(sim_consts.n_particles) - c = bundle_c[particle_ind, bundle_snapshot] - φ = bundle_φ[particle_ind, bundle_snapshot] + args.particle_xs[][particle_ind] = c[1] + args.particle_ys[][particle_ind] = c[2] - args.particle_xs[][particle_ind] = c[1] - args.particle_ys[][particle_ind] = c[2] + color = angle_color(φ, args.color_scheme) + args.particle_colors[][particle_ind] = color - color = angle_color(φ, args.color_scheme) - args.particle_colors[][particle_ind] = color - - if args.show_interaction_circle - args.interaction_colors[][particle_ind] = ColorSchemes.ColorTypes.RGBA( - color, 0.08 - ) - end - - if args.show_skin_circle - args.skin_colors[][particle_ind] = ColorSchemes.ColorTypes.RGBA(color, 0.04) - end + if args.show_interaction_circle + args.interaction_colors[][particle_ind] = ColorSchemes.ColorTypes.RGBA( + color, 0.08 + ) end - if args.show_center_of_mass - center_of_mass = ReCo.center_of_mass( - view(bundle_c, :, bundle_snapshot), sim_consts.half_box_len - ) - args.center_of_mass_point[] = Point(center_of_mass) + if args.show_skin_circle + args.skin_colors[][particle_ind] = ColorSchemes.ColorTypes.RGBA(color, 0.04) end - if args.n_bundle == 1 && bundle_snapshot == 1 - scatter!( - args.ax, - args.particle_xs, - args.particle_ys; - markersize=2 * sim_consts.particle_radius, - markerspace=:data, - color=args.particle_colors, - ) + if args.show_frame_diff + first_ind = 2 * particle_ind - 1 + second_ind = 2 * particle_ind + + first_bundle_snapshot = bundle_snapshot - 1 + second_bundle_snapshot = bundle_snapshot + + if bundle_snapshot == 1 + first_bundle_snapshot = 1 + end + + args.segment_xs[][first_ind] = bundle.c[particle_ind, first_bundle_snapshot][1] + args.segment_xs[][second_ind] = bundle.c[particle_ind, second_bundle_snapshot][1] + + args.segment_ys[][first_ind] = bundle.c[particle_ind, first_bundle_snapshot][2] + args.segment_ys[][second_ind] = bundle.c[particle_ind, second_bundle_snapshot][2] + end + end + + if args.show_center_of_mass + center_of_mass = ReCo.center_of_mass( + view(bundle.c, :, bundle_snapshot), sim_consts.half_box_len + ) + args.center_of_mass_point[] = Point(center_of_mass) + end +end + +function init_animation(args, sim_consts::ReCo.SimConsts, first_bundle::ReCo.Bundle) + update_values!(args, sim_consts, first_bundle, 1) + + scatter!( + args.ax, + args.particle_xs, + args.particle_ys; + markersize=2 * sim_consts.particle_radius, + markerspace=:data, + color=args.particle_colors, + ) + + if args.show_center_of_mass + scatter!( + args.ax, + args.center_of_mass_point; + markersize=6 * sim_consts.particle_radius, + markerspace=:data, + color=ColorSchemes.ColorTypes.RGBA(1.0, 1.0, 1.0, 0.6), + ) + end + + if args.show_interaction_circle + scatter!( + args.ax, + args.particle_xs, + args.particle_ys; + markersize=2 * sim_consts.interaction_radius, + markerspace=:data, + color=args.interaction_colors, + ) + end + + if args.show_skin_circle + scatter!( + args.ax, + args.particle_xs, + args.particle_ys; + markersize=2 * sim_consts.skin_radius, + markerspace=:data, + color=args.skin_colors, + ) + end + + if args.show_frame_diff + linesegments!(args.ax, args.segment_xs, args.segment_ys; color=args.particle_colors) + end + + return nothing +end + +function animate_bundle!( + args, + sim_consts::ReCo.SimConsts, + io, + bundle::ReCo.Bundle, + skip_first_bundle_snapshot::Bool, +) + for bundle_snapshot in 1:length(bundle.t) + if !skip_first_bundle_snapshot + update_values!(args, sim_consts, bundle, bundle_snapshot) + + if args.show_frame_diff + Observables.notify(args.segment_xs) + Observables.notify(args.segment_ys) + end + + Observables.notify(args.particle_xs) + Observables.notify(args.particle_ys) + Observables.notify(args.particle_colors) if args.show_center_of_mass - scatter!( - args.ax, - args.center_of_mass_point; - markersize=6 * sim_consts.particle_radius, - markerspace=:data, - color=ColorSchemes.ColorTypes.RGBA(1.0, 1.0, 1.0, 0.6), - ) + Observables.notify(args.center_of_mass_point) end if args.show_interaction_circle - scatter!( - args.ax, - args.particle_xs, - args.particle_ys; - markersize=2 * sim_consts.interaction_radius, - markerspace=:data, - color=args.interaction_colors, - ) + Observables.notify(args.interaction_colors) end if args.show_skin_circle - scatter!( - args.ax, - args.particle_xs, - args.particle_ys; - markersize=2 * sim_consts.skin_radius, - markerspace=:data, - color=args.skin_colors, - ) - end - - println("Recording started!") - else - if args.show_frame_diff && bundle_snapshot > 1 - @simd for i in 1:(sim_consts.n_particles) - first_ind = 2 * i - 1 - second_ind = 2 * i - frame_min_1 = bundle_snapshot - 1 - - args.segment_xs[][first_ind] = bundle_c[i, frame_min_1][1] - args.segment_xs[][second_ind] = bundle_c[i, bundle_snapshot][1] - - args.segment_ys[][first_ind] = bundle_c[i, frame_min_1][2] - args.segment_ys[][second_ind] = bundle_c[i, bundle_snapshot][2] - end - - if bundle_snapshot == 2 - linesegments!( - args.ax, - args.segment_xs, - args.segment_ys; - color=args.particle_colors, - ) - end - - notify(args.segment_xs) - notify(args.segment_ys) - end - - notify(args.particle_xs) - notify(args.particle_ys) - notify(args.particle_colors) - - if args.show_center_of_mass - notify(args.center_of_mass_point) - end - - if args.show_interaction_circle - notify(args.interaction_colors) - end - - if args.show_skin_circle - notify(args.skin_colors) + Observables.notify(args.skin_colors) end end - args.ax.title = "t = $(round(bundle_t[bundle_snapshot], digits=3))" + args.ax.title = "t = $(round(bundle.t[bundle_snapshot], digits=3))" - recordframe!(args.io) + recordframe!(io) end return nothing @@ -190,85 +204,91 @@ function animate( animation_path = "$sim_dir/animation.mkv" + particle_xs = Observable(Vector{Float64}(undef, n_particles)) + particle_ys = Observable(Vector{Float64}(undef, n_particles)) + + particle_colors = Observable( + Vector{ColorSchemes.ColorTypes.RGB{Float64}}(undef, n_particles) + ) + + center_of_mass_point = + segment_xs = + segment_ys = + interaction_circle_xs = + interaction_circle_ys = + skin_circle_xs = + skin_circle_ys = interaction_colors = skin_colors = nothing + + if show_center_of_mass + center_of_mass_point = Observable(Point2(0.0, 0.0)) + end + + if show_interaction_circle + interaction_circle_xs = Observable(Vector{Float64}(undef, n_particles)) + interaction_circle_ys = Observable(Vector{Float64}(undef, n_particles)) + + interaction_colors = Observable( + Vector{ColorSchemes.ColorTypes.RGBA{Float64}}(undef, n_particles) + ) + end + + if show_skin_circle + skin_circle_xs = Observable(Vector{Float64}(undef, n_particles)) + skin_circle_ys = Observable(Vector{Float64}(undef, n_particles)) + + skin_colors = Observable( + Vector{ColorSchemes.ColorTypes.RGBA{Float64}}(undef, n_particles) + ) + end + + if show_frame_diff + segment_xs = Observable(zeros(Float64, 2 * n_particles)) + segment_ys = Observable(zeros(Float64, 2 * n_particles)) + end + + args = (; + # Input + show_center_of_mass, + show_interaction_circle, + show_skin_circle, + show_frame_diff, + # Internal + ax, + particle_xs, + particle_ys, + particle_colors, + center_of_mass_point, + segment_xs, + segment_ys, + interaction_circle_xs, + interaction_circle_ys, + skin_circle_xs, + skin_circle_ys, + interaction_colors, + skin_colors, + color_scheme, + ) + + bundle_paths = ReCo.sorted_bundle_paths(sim_dir) + + bundle::ReCo.Bundle = JLD2.load_object(bundle_paths[1]) + init_animation(args, sim_consts, bundle) + + progress = ProgressMeter.Progress( + length(bundle_paths); dt=2, enabled=show_progress, desc="Animation: " + ) + record(fig, animation_path; framerate=framerate) do io - particle_xs = Observable(Vector{Float64}(undef, n_particles)) - particle_ys = Observable(Vector{Float64}(undef, n_particles)) - - particle_colors = Observable( - Vector{ColorSchemes.ColorTypes.RGB{Float64}}(undef, n_particles) - ) - - center_of_mass_point = - segment_xs = - segment_ys = - interaction_circle_xs = - interaction_circle_ys = - skin_circle_xs = - skin_circle_ys = interaction_colors = skin_colors = nothing - - if show_center_of_mass - center_of_mass_point = Observable(Point2(0.0, 0.0)) - end - - if show_interaction_circle - interaction_circle_xs = Observable(Vector{Float64}(undef, n_particles)) - interaction_circle_ys = Observable(Vector{Float64}(undef, n_particles)) - - interaction_colors = Observable( - Vector{ColorSchemes.ColorTypes.RGBA{Float64}}(undef, n_particles) - ) - end - - if show_skin_circle - skin_circle_xs = Observable(Vector{Float64}(undef, n_particles)) - skin_circle_ys = Observable(Vector{Float64}(undef, n_particles)) - - skin_colors = Observable( - Vector{ColorSchemes.ColorTypes.RGBA{Float64}}(undef, n_particles) - ) - end - - if show_frame_diff - segment_xs = Observable(zeros(Float64, 2 * n_particles)) - segment_ys = Observable(zeros(Float64, 2 * n_particles)) - end - - bundle_paths = ReCo.sorted_bundle_paths(sim_dir) - - progress = ProgressMeter.Progress( - length(bundle_paths); dt=2, enabled=show_progress, desc="Animation: " - ) + println("Started recording!") for (n_bundle, bundle_path) in enumerate(bundle_paths) - bundle::ReCo.Bundle = JLD2.load_object(bundle_path) + if n_bundle != 1 + bundle = JLD2.load_object(bundle_path) + end - args = (; - # Input - show_center_of_mass, - show_interaction_circle, - show_skin_circle, - show_frame_diff, - # Internal - io, - ax, - bundle, - particle_xs, - particle_ys, - particle_colors, - center_of_mass_point, - segment_xs, - segment_ys, - interaction_circle_xs, - interaction_circle_ys, - skin_circle_xs, - skin_circle_ys, - interaction_colors, - skin_colors, - color_scheme, - n_bundle, - ) + skip_first_bundle_snapshot = n_bundle == 1 - animate_bundle!(args, sim_consts) + animate_bundle!(args, sim_consts, io, bundle, skip_first_bundle_snapshot) ProgressMeter.next!(progress) end diff --git a/visualization/Manifest.toml b/visualization/Manifest.toml index 254460f..08a9ea7 100644 --- a/visualization/Manifest.toml +++ b/visualization/Manifest.toml @@ -1185,7 +1185,7 @@ version = "0.4.3" [[deps.ReCo]] deps = ["CellListMap", "Dates", "Distributions", "Flux", "Intervals", "JLD2", "LaTeXStrings", "LinearAlgebra", "ProgressMeter", "Random", "ReinforcementLearning", "StaticArrays", "UnicodePlots"] -git-tree-sha1 = "7b7f1cf73718423fa293397ce7796055549a0686" +git-tree-sha1 = "50559f3f3d0a26055675cd78776b8bafe1bada3a" repo-rev = "main" repo-url = ".." uuid = "b25f7548-fcc9-4c91-bc24-841b54f4dd54"