Skip to content

Commit 7595669

Browse files
committed
Initial commit.
0 parents  commit 7595669

32 files changed

+1984
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.vscode
2+
.DS_store

Fig1_introexample.jl

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using PointProcessFilters, CairoMakie, Meshes, ProgressMeter, RCall, LinearAlgebra
2+
3+
## Simulation
4+
@info "Perform the simulation..."
5+
side_length = 200
6+
side_padding = 50
7+
box_x = [-side_padding, side_length + side_padding]
8+
box_y = box_x
9+
10+
λ = 0.01
11+
kappa = 0.8λ
12+
scale = 3
13+
mu = λ / kappa
14+
15+
@rput kappa scale mu box_x box_y
16+
R"""
17+
library(spatstat)
18+
set.seed(1234)
19+
simulated_process = rThomas(kappa, scale, mu, win=owin(box_x, box_y))
20+
"""
21+
@rget simulated_process
22+
simulated_points = PointSet(Meshes.Point.(simulated_process[:x], simulated_process[:y]))
23+
@info "points simulated."
24+
25+
## Filtering
26+
@info "Apply the filters..."
27+
interval = [0, 0.05, 0.1, 0.15]
28+
filtered_process = [
29+
centeredcirclepass(simulated_points, interval[2]),
30+
ringpass(simulated_points, interval[2], interval[3]),
31+
ringpass(simulated_points, interval[3], interval[4]),
32+
]
33+
filter_resolution = 100
34+
filter_x = range(0, side_length, filter_resolution)
35+
filter_y = filter_x
36+
Y = @showprogress "evaluating filters... " [y.(filter_x, filter_y')
37+
for y in filtered_process]
38+
Ylims = extrema(stack(Y))
39+
@info "filtered processes computed."
40+
41+
## sdf of thomas process
42+
function thomassdf(k; kappa, scale, mu)
43+
return kappa * mu * (1 + mu * exp(-scale^2 * (2π)^2 * norm(k)^2))
44+
end
45+
46+
## plotting
47+
@info "Start plotting..."
48+
fig_res = (80, 80)
49+
50+
## plot the spectra
51+
@info "- plotting spectra"
52+
figure = Figure(resolution = fig_res .* (1, 2 / 3), figure_padding = 1)
53+
ax = Axis(figure[1, 1], yscale = identity, xticks = [0], yticks = [0], xgridcolor = :black,
54+
ygridcolor = :black)
55+
band!(ax, interval, zeros(length(interval)), fill(0.025, length(interval)),
56+
color = (:lightgrey, 0.5))
57+
vlines!(interval, color = :black, linestyle = :dash, linewidth = 1 / 2)
58+
lines!(ax, range(0, 0.2, 1000), x -> thomassdf(x, kappa = kappa, scale = scale, mu = mu),
59+
color = :black)
60+
61+
ylims!(ax, (-0.001, 0.025))
62+
hidedecorations!(ax, grid = false)
63+
hidespines!(ax)
64+
resize_to_layout!(figure)
65+
66+
save("fig/fig1/sdf.pdf", figure)
67+
figure
68+
69+
## plot the points
70+
@info "- plotting points"
71+
figure = Figure(resolution = fig_res, figure_padding = 1)
72+
ax = Axis(figure[1, 1], limits = (0, side_length, 0, side_length))
73+
viz!(ax, simulated_points, color = :black, pointsize = 2)
74+
hidedecorations!(ax)
75+
resize_to_layout!(figure)
76+
save("fig/fig1/points.pdf", figure)
77+
figure
78+
79+
## plot filters
80+
@info "- plotting filters"
81+
for i in eachindex(Y)
82+
figure_filt = Figure(resolution = fig_res, figure_padding = 1)
83+
ax_filt = Axis(figure_filt[1, 1])
84+
contourf!(ax_filt, filter_x, filter_y, Y[i], colorrange = Ylims, colormap = :tempo)
85+
hidedecorations!(ax_filt)
86+
save("fig/fig1/filtered_$i.pdf", figure_filt)
87+
end
88+
89+
@info "Finished plotting."

Fig2_lgcp.jl

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
using CairoMakie, PointProcessFilters, ProgressMeter, GaussianRandomFields, RCall, Meshes
2+
import Meshes: Point, PointSet, Box
3+
include("src/iso_pgram.jl")
4+
import .IsoPP: periodogram_iso
5+
6+
## set parameter
7+
side_length = 100
8+
side_padding = 25
9+
box_x = [-side_padding, side_length + side_padding]
10+
box_y = box_x
11+
nu = 3 / 2
12+
lengthscale = 10
13+
sigma = sqrt(2)
14+
lambda_noise = 0.05
15+
16+
## simualate the random field (R package currently broken so cant use spatstat)
17+
import Random;
18+
Random.seed!(1234);
19+
cov = CovarianceFunction(2, Matern(lengthscale, nu, σ = sigma))
20+
grid_sides = range(box_x..., 250), range(box_y..., 250)
21+
grf = GaussianRandomField(cov, CirculantEmbedding(), grid_sides...)
22+
intensity = exp.(GaussianRandomFields.sample(grf) .- 4)
23+
heatmap(intensity)
24+
25+
##
26+
@rput intensity box_x box_y lambda_noise
27+
R"""
28+
library(spatstat)
29+
set.seed(1234)
30+
window = owin(box_x, box_y)
31+
intensity_image = as.im(aperm(intensity), window)
32+
signal_process = rpoispp(intensity_image, nsim=2)
33+
noise_process = rpoispp(lambda_noise, win=window, nsim=2)
34+
"""
35+
@rget signal_process noise_process
36+
sim_names = collect(keys(signal_process))
37+
signal = Dict([k => PointSet(Point.(signal_process[k][:x], signal_process[k][:y]))
38+
for k in sim_names])
39+
noisy = Dict([k => PointSet([Point.(signal_process[k][:x], signal_process[k][:y]);
40+
Point.(noise_process[k][:x], noise_process[k][:y])])
41+
for k in sim_names])
42+
43+
## apply filters
44+
@info "Filtering (may take a few minutes)..."
45+
area = diff(box_x)[1] * diff(box_y)[1]
46+
filtered = Dict([k => centeredcirclepass(noisy[k], 0.05).(grid_sides[1], grid_sides[2]') .-
47+
length(noisy[k]) / area for k in sim_names])
48+
@info "filtering completed."
49+
50+
##
51+
clims = extrema(vcat(values(filtered)...))
52+
f = Figure()
53+
heatmap(f[1, 1], grid_sides..., intensity, colormap = :matter)
54+
for i in 1:2
55+
viz(f[2, i], signal[sim_names[i]], pointsize = 4, color = :black,
56+
axis = (limits = (0, 100, 0, 100),))
57+
viz(f[3, i], noisy[sim_names[i]], pointsize = 4, color = :black,
58+
axis = (limits = (0, 100, 0, 100),))
59+
heatmap(f[4, i], grid_sides..., filtered[sim_names[i]], colormap = :tempo,
60+
colorrange = clims)
61+
end
62+
f
63+
64+
region = Box(Point(box_x[1],box_y[1]), Point(box_x[2],box_y[2]))
65+
pgram = Dict([s=>periodogram_iso(noisy[s], region, (1:20).*0.01) for s in sim_names])
66+
λ = Dict([s=>length(noisy[s]) / area for s in sim_names])
67+
68+
##
69+
@info "Making figures..."
70+
clims = extrema(vcat(values(filtered)...))
71+
function make_figure()
72+
f = Figure(resolution = (100, 100), figure_padding = 1)
73+
ax = Axis(f[1, 1], limits = (0, 100, 0, 100), aspect = 1)
74+
hidedecorations!(ax)
75+
return f, ax
76+
end
77+
78+
figure, ax = make_figure()
79+
contourf!(ax, grid_sides..., intensity, colormap = :matter)
80+
save("fig/fig2/intensity.pdf", figure)
81+
82+
for i in 1:2
83+
figure_p, ax_p = make_figure()
84+
viz!(ax_p, signal[sim_names[i]], pointsize = 2, color = :black)
85+
save("fig/fig2/cp$i.pdf", figure_p)
86+
87+
figure_p, ax_p = make_figure()
88+
viz!(ax_p, noisy[sim_names[i]], pointsize = 2, color = :black)
89+
save("fig/fig2/pts$i.pdf", figure_p)
90+
91+
figure_p, ax_p = make_figure()
92+
contourf!(ax_p, grid_sides..., filtered[sim_names[i]], colormap = :tempo,
93+
colorrange = clims)
94+
save("fig/fig2/filt$i.pdf", figure_p)
95+
96+
figure_p = Figure(resolution = (100,60), fontsize=8, figure_padding=1)
97+
ax_p = Axis(figure_p[1,1], xticks = [0], yticks=[0], xgridcolor=:black, ygridcolor=:black)
98+
ylims!(ax_p, (-1,21))
99+
band!(ax_p, [0,0.05], fill(-1,2), fill(21,2), color = (:lightgrey,0.5))
100+
vlines!(ax_p, [0,0.05], color = :black, linestyle=:dash, linewidth=1/2)
101+
lines!(ax_p, pgram[sim_names[i]].t, pgram[sim_names[i]].sdf./pgram[sim_names[i]].lambda.-1, color = :black)
102+
hidedecorations!(ax_p, grid=false)
103+
hidespines!(ax_p)
104+
save("fig/fig2/sdf_$i.pdf", figure_p)
105+
end
106+
@info "figures finished."

Fig3_lansingwoods.jl

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using PointProcessFilters, CairoMakie, Meshes, ProgressMeter
2+
import Meshes: Point, PointSet, Box
3+
using RCall
4+
include("src/iso_pgram.jl")
5+
import .IsoPP: periodogram_iso
6+
7+
@info "Begin analysis of spatstat data"
8+
9+
R"""
10+
library(spatstat)
11+
treedata = lansing
12+
"""
13+
@rget treedata
14+
15+
lansing_points = Dict([s=>PointSet(unique(Point.(treedata[:x],treedata[:y])[treedata[:marks].==s])) for s in unique(treedata[:marks])])
16+
region = Box(Point(0,0), Point(1,1))
17+
18+
species = ["hickory", "maple"]
19+
λ = Dict([s=>length(lansing_points[s]) / measure(region) for s in species])
20+
ppfilt = Dict([s=>centeredcirclepass(lansing_points[s], 6) for s in species])
21+
22+
lags = range(0,1,100)
23+
pp_w = Dict(@showprogress [s=>ppfilt[s].(lags,lags').-λ[s] for s in species])
24+
25+
##
26+
pgram = Dict([s=>periodogram_iso(lansing_points[s], region, 1:20) for s in species])
27+
28+
folder = "fig/fig3/"
29+
clims = extrema(stack([pp_w[sp] for sp in species]))
30+
for sp in species
31+
figure_p = Figure(resolution = (100,100), fontsize=8, figure_padding=1)
32+
ax_p = Axis(figure_p[1,1], limits=(0,1,0,1))
33+
hidedecorations!(ax_p)
34+
viz!(ax_p, lansing_points[sp], pointsize = 2, color = :black)
35+
save(folder * "pts_$sp.pdf", figure_p)
36+
37+
figure_p = Figure(resolution = (100,60), fontsize=8, figure_padding=1)
38+
ax_p = Axis(figure_p[1,1], xticks = [0], yticks=[0], xgridcolor=:black, ygridcolor=:black)
39+
ylims!(ax_p, (-1,15))
40+
xlims!(ax_p, (-1,21))
41+
band!(ax_p, [0,6], fill(-1,2), fill(15,2), color = (:lightgrey,0.5))
42+
vlines!(ax_p, [0,6], color = :black, linestyle=:dash, linewidth=1/2)
43+
lines!(ax_p, pgram[sp].t, pgram[sp].sdf./pgram[sp].lambda.-1, color = :black)
44+
hidedecorations!(ax_p, grid=false)
45+
hidespines!(ax_p)
46+
save(folder * "sdf_$sp.pdf", figure_p)
47+
48+
figure_p = Figure(resolution = (100,100), fontsize=8, figure_padding=1)
49+
ax_p = Axis(figure_p[1,1])
50+
hidedecorations!(ax_p)
51+
cf=contourf!(ax_p, lags, lags, pp_w[sp], colorrange = clims, colormap=:tempo)
52+
save(folder * "filt_$sp.pdf", figure_p)
53+
end
54+
55+
@info "finished plotting."

Fig4_impulseresponses.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using CairoMakie, PointProcessFilters, Meshes, ProgressMeter
2+
import CairoMakie: Point2f, Circle, Rect
3+
import PointProcessFilters: CenteredBox, CenteredBall
4+
import Meshes: Point, Box
5+
6+
## set parameters
7+
r1 = 5
8+
r2 = 10
9+
rsmall = (r2 - r1) / 2
10+
defaults = (color = (:gray), strokewidth = 0)
11+
12+
## make figure
13+
figure = Figure(resolution = 300 .* (1, 2 / 4), figure_padding = 1)
14+
ax = [Axis(figure[1, i], aspect = 1, limits = (r2 + 1) .* (-1, 1, -1, 1)) for i in 1:4]
15+
hidedecorations!.(ax)
16+
hidespines!.(ax)
17+
poly!(ax[1], Circle(Point2f(0, 0), r2); defaults...)
18+
poly!(ax[1], Circle(Point2f(0, 0), r1); color = :white)
19+
20+
poly!(ax[2], Circle(Point2f(5, r1 + rsmall), rsmall); defaults...)
21+
poly!(ax[2], Circle(Point2f(-5, -r1 - rsmall), rsmall); defaults...)
22+
23+
poly!(ax[3], Rect(-r2, -r2, 2r2, 2r2); defaults...)
24+
poly!(ax[3], Rect(-r1, -r1, 2r1, 2r1); color = :white)
25+
26+
poly!(ax[4], Rect(5 - rsmall, r1, 2rsmall, 2rsmall); defaults...)
27+
poly!(ax[4], Rect(-5 + rsmall, -r1, -2rsmall, -2rsmall); defaults...)
28+
29+
regions = (CenteredBall{2}(r2) - CenteredBall{2}(r1),
30+
Ball(Point(5, r1 + rsmall), rsmall),
31+
CenteredBox(Point(r2, r2)) - CenteredBox(Point(r1, r1)),
32+
Box(Point(5 - rsmall, r1), Point(5 + rsmall, r1 + 2rsmall)))
33+
h = impulse_response.(RegionPassFilter.(regions))
34+
x = range(-0.5, 0.5, 100)
35+
h_evaluated = @showprogress "evaluating ir... " [Makie.pseudolog10.(h[i].(x, x'))
36+
for i in 1:4]
37+
38+
ax = [Axis(f[2, i], aspect = 1) for i in 1:4]
39+
hidedecorations!.(ax)
40+
hidespines!.(ax)
41+
for i in 1:4
42+
heatmap!(ax[i], x, x, h_evaluated[i], colormap = :tempo,
43+
colorrange = extrema(stack(h_evaluated)), interpolate = true)
44+
end
45+
46+
save("fig/fig4/transfer_functions.pdf", figure)
47+
figure

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Jake P. Grainger
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)