Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Background Map for Plotting #170

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## v0.5.1-dev

- Add `classical_delay` and `quantum_delay` as keyword arguments to the `RegisterNet` constructor to set a default global network edge latency.
- Plots of networks can now overlay real-world maps (see `generate_map`).

## v0.5.0 - 2024-10-16

Expand Down
5 changes: 4 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,22 @@ SumTypes = "8e1ec7a9-0e02-4297-b0fe-6433085c89f2"

[weakdeps]
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6"

[extensions]
QuantumSavoryGeoMakie = ["GeoMakie", "Makie"]
QuantumSavoryMakie = "Makie"

[compat]
Combinatorics = "1"
ConcurrentSim = "1.4.1"
Distributions = "0.25.90"
DocStringExtensions = "0.9"
GeoMakie = "0.7.8"
Graphs = "1.9"
IterTools = "1.4.0"
LinearAlgebra = "1"
Makie = "0.20, 0.21"
Makie = "0.21"
NetworkLayout = "0.4.4"
PrecompileTools = "1"
Printf = "1"
Expand Down
30 changes: 30 additions & 0 deletions ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module QuantumSavoryGeoMakie

import Makie, GeoMakie
using GeoMakie: GeoAxis, image!, poly!, naturalearth

"""
Generates a default map with country and state boundaries and returns a GeoAxis. The returned GeoAxis can be used as an input for `registernetplot_axis`.

For borders, the optional `scale` parameter can be set to 10, 50, or 110, corresponding to Natural Earth resolutions of 1:10m, 1:50m, and 1:110m.
"""
function generate_map(subfig::Makie.GridPosition, scale::Int=110)
if scale ∉ (10, 50, 110)
error("Invalid scale value: scale must be 10, 50, or 110.")

Check warning on line 13 in ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl#L11-L13

Added lines #L11 - L13 were not covered by tests
end
ax = GeoAxis(subfig; limits=((-180, 180), (-90, 90)), dest="+proj=longlat +datum=WGS84")
countries = naturalearth("admin_0_countries", scale)
states = naturalearth("admin_1_states_provinces_lakes", scale)
image!(ax, (-180, 180), (-90, 90), GeoMakie.earth() |> rotr90; interpolate=false, inspectable=false)
poly!(ax, GeoMakie.land(); color=:lightyellow, strokecolor=:transparent, inspectable=false)
poly!(ax, GeoMakie.to_multipoly.(countries.geometry), color=:transparent, strokecolor=:black, strokewidth=1, inspectable=false)
poly!(ax, GeoMakie.to_multipoly.(states.geometry); color=:transparent, strokecolor=:grey, strokewidth=0.7, inspectable=false)
return ax

Check warning on line 22 in ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl#L15-L22

Added lines #L15 - L22 were not covered by tests
end

function generate_map()
fig = Makie.Figure()
generate_map(fig[1, 1])

Check warning on line 27 in ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryGeoMakie/QuantumSavoryGeoMakie.jl#L25-L27

Added lines #L25 - L27 were not covered by tests
end

end
35 changes: 26 additions & 9 deletions ext/QuantumSavoryMakie/QuantumSavoryMakie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -280,27 +280,44 @@

##

"""Draw the given registers on a given Makie axis.
Krastanov marked this conversation as resolved.
Show resolved Hide resolved
"""Draw the given registers on a given Makie axis or a subfigure.

It returns a tuple of (subfigure, axis, plot, observable).
The observable can be used to issue a `notify` call that updates
the plot with the current state of the network."""
function registernetplot_axis(subfig, registersobservable; infocli=true, datainspector=true, kwargs...)
ax = Makie.Axis(subfig)
function registernetplot_axis end

function registernetplot_axis(ax::Makie.AbstractAxis, registersobservable; infocli=true, datainspector=true, map=false, kwargs...)

Check warning on line 290 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L290

Added line #L290 was not covered by tests
p = registernetplot!(ax, registersobservable; kwargs...)
ax.aspect = Makie.DataAspect()
Makie.hidedecorations!(ax)
Makie.hidespines!(ax)
if hasmethod(Makie.hidedecorations!, Tuple{typeof(ax)})
Makie.hidedecorations!(ax)

Check warning on line 294 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L293-L294

Added lines #L293 - L294 were not covered by tests
end
if hasmethod(Makie.hidespines!, Tuple{typeof(ax)})
Makie.hidespines!(ax)

Check warning on line 297 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L296-L297

Added lines #L296 - L297 were not covered by tests
end
Makie.deregister_interaction!(ax, :rectanglezoom)
if infocli
rnh = RNHandler(p)
Makie.register_interaction!(ax, :registernet, rnh)
end
if datainspector
DataInspector(subfig)
DataInspector(ax.parent)

Check warning on line 305 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L305

Added line #L305 was not covered by tests
end
Makie.autolimits!(ax)
subfig, ax, p, p[1]
if hasmethod(Makie.autolimits!, Tuple{typeof(ax)})
Makie.autolimits!(ax)

Check warning on line 308 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L307-L308

Added lines #L307 - L308 were not covered by tests
end
ax.parent, ax, p, p[1]

Check warning on line 310 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L310

Added line #L310 was not covered by tests
end

function registernetplot_axis(subfig::Makie.GridPosition, registersobservable; infocli=true, datainspector=true, kwargs...)
registernetplot_axis(Makie.Axis(subfig), registersobservable; infocli, datainspector, kwargs...)

Check warning on line 314 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L313-L314

Added lines #L313 - L314 were not covered by tests
end

function registernetplot_axis(registersobservable; infocli=true, datainspector=true, kwargs...)
fig = Figure()
ax = Axis(fig[1, 1])
registernetplot_axis(ax, registersobservable; infocli, datainspector, kwargs...)

Check warning on line 320 in ext/QuantumSavoryMakie/QuantumSavoryMakie.jl

View check run for this annotation

Codecov / codecov/patch

ext/QuantumSavoryMakie/QuantumSavoryMakie.jl#L317-L320

Added lines #L317 - L320 were not covered by tests
end

##
Expand Down Expand Up @@ -358,4 +375,4 @@
tuple(Makie.shift_project(ax.scene, p.registercoords[][reg].+(0,slot-1))...);
end

end
end
2 changes: 1 addition & 1 deletion src/QuantumSavory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export
# noninstant.jl
AbstractNoninstantOperation, NonInstantGate, ConstantHamiltonianEvolution,
# plots.jl
registernetplot, registernetplot!, registernetplot_axis, resourceplot_axis
registernetplot, registernetplot!, registernetplot_axis, resourceplot_axis, generate_map


#TODO you can not assume you can always in-place modify a state. Have all these functions work on stateref, not stateref[]
Expand Down
45 changes: 40 additions & 5 deletions src/plots.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,59 @@
"""Draw the given register network.

Requires a Makie backend be already imported."""
function registernetplot end
function registernetplot(args...; kwargs...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workaround of using get_extension is something I set up for use with types and structs, but it is not a very good way to deal with functions, given the multimethod nature of julia.
Methods of functions can be added in extensions -- that would be much more natural than what we are doing here, of using a new function in a new namespace.

For now we can probably keep this implementation, but it would be important to create an issue to track fixing this hack.

Potentially a better way to do this would be to have a hint attached to method errors. Something like what is done in this PR https://github.com/QuantumSavory/QuantumClifford.jl/pull/416/files# but just warning that the method error happened because the necessary package was not imported.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, it seems it is worse than that. Currently the way you have namespaced things it looks like a method is being overridden instead of a new function being made. That can be easily fixed by just restricting what is being imported in the namespace and keeping your current implementation.

But given that things need to be fixed anyway, I suggest doing the proper fix with method error hints that I described above.

Here is the errors I am currently getting

[ Info: Precompiling QuantumSavoryMakie [92a66160-645b-5231-a29a-c456122f462a] (cache misses: wrong dep version loaded (4), incompatible header (2))
WARNING: Method definition registernetplot(Any...) in module QuantumSavory at /home/stefan/Documents/ScratchSpace/quantumjulia/QuantumSavory.jl/src/plots.jl:4 overwritten in module QuantumSavoryMakie at /home/stefan/.julia/packages/MakieCore/EU17Y/src/recipes.jl:194.
ERROR: Method overwriting is not permitted during Module precompilation. Use `__precompile__(false)` to opt-out of precompilation.

ext = Base.get_extension(QuantumSavory, :QuantumSavoryMakie)
if isnothing(ext)
throw("`registernetplot` requires the package `Makie`; please make sure `Makie` is installed and imported first.")

Check warning on line 7 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L4-L7

Added lines #L4 - L7 were not covered by tests
end
return ext.registernetplot(args...; kwargs...)

Check warning on line 9 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L9

Added line #L9 was not covered by tests
end

"""Draw the given register network on a given Makie axis.

Requires a Makie backend be already imported."""
function registernetplot! end
function registernetplot!(args...; kwargs...)
ext = Base.get_extension(QuantumSavory, :QuantumSavoryMakie)
if isnothing(ext)
throw("`registernetplot!` requires the package `Makie`; please make sure `Makie` is installed and imported first.")

Check warning on line 18 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L15-L18

Added lines #L15 - L18 were not covered by tests
end
return ext.registernetplot!(args...; kwargs...)

Check warning on line 20 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L20

Added line #L20 was not covered by tests
end

"""Draw the given register network on a given Makie subfigure and modify the axis with numerous visualization enhancements.
"""Draw the given register network on a given Makie axis or subfigure and modify the axis with numerous visualization enhancements.

Requires a Makie backend be already imported."""
function registernetplot_axis end
function registernetplot_axis(args...; kwargs...)
ext = Base.get_extension(QuantumSavory, :QuantumSavoryMakie)
if isnothing(ext)
throw("`registernetplot_axis` requires the package `Makie`; please make sure `Makie` is installed and imported first.")

Check warning on line 29 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L26-L29

Added lines #L26 - L29 were not covered by tests
end
return ext.registernetplot_axis(args...; kwargs...)

Check warning on line 31 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L31

Added line #L31 was not covered by tests
end

"""Draw the various resources and locks stored in the given meta-graph on a given Makie axis.

Requires a Makie backend be already imported."""
function resourceplot_axis end
function resourceplot_axis(args...; kwargs...)
ext = Base.get_extension(QuantumSavory, :QuantumSavoryMakie)
if isnothing(ext)
throw("`resourceplot_axis` requires the package `Makie`; please make sure `Makie` is installed and imported first.")

Check warning on line 40 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L37-L40

Added lines #L37 - L40 were not covered by tests
end
return ext.resourceplot_axis(args...; kwargs...)

Check warning on line 42 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L42

Added line #L42 was not covered by tests
end

"""Show the metadata tooltip for a given register slot."""
function showmetadata end

function showonplot end

"""Generates a default map with country and state boundaries and returns a GeoAxis. The returned GeoAxis can be used as an input for registernetplot_axis.

The `GeoMakie` package must be installed and imported."""
function generate_map(args...; kwargs...)
ext = Base.get_extension(QuantumSavory, :QuantumSavoryGeoMakie)
if isnothing(ext)
throw("`generate_map` requires the package `GeoMakie`; please make sure `GeoMakie` is installed and imported first.")

Check warning on line 56 in src/plots.jl

View check run for this annotation

Codecov / codecov/patch

src/plots.jl#L56

Added line #L56 was not covered by tests
end
return ext.generate_map(args...; kwargs...)
end
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
Expand Down
32 changes: 32 additions & 0 deletions test/test_plotting_3_maps.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using FileIO
using GeoMakie
using QuantumSavory

sizes = [2,3,5]
registers = Register[]
for s in sizes
traits = [Qubit() for _ in 1:s]
bg = [T2Dephasing(1.0) for _ in 1:s]
push!(registers, Register(traits,bg))
end
network = RegisterNet(registers)
map_axis = generate_map()
coords = [Point2f(-71, 42), Point2f(-111, 34), Point2f(-122, 37)]
_, _, plt, netobs = registernetplot_axis(map_axis, network, registercoords=coords)
save(File{format"PNG"}(mktemp()[1]), fig)

initialize!(network[1,1])
initialize!(network[2,1])
notify(netobs)
save(File{format"PNG"}(mktemp()[1]), fig)

apply!([network[1,1],network[2,1]], CNOT)
notify(netobs)
save(File{format"PNG"}(mktemp()[1]), fig)

display(fig)

fig = Figure()
map_axis = generate_map(fig[1, 1])
_, _, plt, netobs = registernetplot_axis(map_axis, network, registercoords=coords)
save(File{format"PNG"}(mktemp()[1]), fig)
3 changes: 3 additions & 0 deletions test/test_plotting_cairo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ end
@testset "arguments and observables and tags" begin
include("test_plotting_2_tags_observables.jl")
end
@testset "background map" begin
include("test_plotting_3_maps.jl")
end
end
3 changes: 3 additions & 0 deletions test/test_plotting_gl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ end
@testset "arguments and observables and tags" begin
include("test_plotting_2_tags_observables.jl")
end
@testset "background map" begin
include("test_plotting_3_maps.jl")
end

@testset "data inspectors" begin # only available in GLMakie
# create a network of qubit registers
Expand Down
Loading