Skip to content

[wip] antimeridian cutting with trees for regridding #283

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

Open
wants to merge 4 commits into
base: as/trees
Choose a base branch
from

Conversation

asinghvi17
Copy link
Member

implement an antimeridian cutting fix ported from the python package

use traittarget in application_level for fix

Merge branch 'as/antimeridian' into as/trees-and-antimeridian

Copy link
Member Author

asinghvi17 commented Mar 18, 2025

Comment on lines 85 to 99
using SpeedyWeather
using GeoMakie

SpeedyWeatherGeoMakieExt = Base.get_extension(SpeedyWeather, :SpeedyWeatherGeoMakieExt)

grid1 = rand(OctaHEALPixGrid, 5 + 100)
grid2 = rand(FullGaussianGrid, 4 + 100)

faces1 = SpeedyWeatherGeoMakieExt.get_faces(grid1)
faces2 = SpeedyWeatherGeoMakieExt.get_faces(grid2)

polys1 = GI.Polygon.(GI.LinearRing.(eachcol(faces1))) .|> GO.fix
polys2 = GI.Polygon.(GI.LinearRing.(eachcol(faces2))) .|> GO.fix

A = @time area_of_intersection_operator(polys1, polys2)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is what the method will ultimately look like...it takes me ~3.5s on my machine, single threaded, to cross reference two ~80,000 element grids.

It's possible to multithread this but not the easiest thing...might need some kind of master-worker setup. We need to multithread within the dual tree query, so maybe we let the query run on one thread and spawn nthreads()*2-2 worker threads that can consume the output from a channel. There would likely also need to be a writer task that is single-threadedly writing to A.

@milankl
Copy link
Member

milankl commented Mar 27, 2025

I'm getting the following error when I try to install this branch

julia> using GeometryOps
Precompiling GeometryOps...
Info Given GeometryOps was explicitly requested, output will be shown live
WARNING: could not import GeometryOpsCore.AutoManifold into GeometryOps
WARNING: could not import GeometryOpsCore.WrongManifoldException into GeometryOps
WARNING: could not import GeometryOpsCore.Algorithm into GeometryOps
WARNING: could not import GeometryOpsCore.AutoAlgorithm into GeometryOps
WARNING: could not import GeometryOpsCore.ManifoldIndependentAlgorithm into GeometryOps
WARNING: could not import GeometryOpsCore.SingleManifoldAlgorithm into GeometryOps
WARNING: could not import GeometryOpsCore.NoAlgorithm into GeometryOps
ERROR: LoadError: UndefVarError: `SingleManifoldAlgorithm` not defined in `GeometryOpsCore`yOps
Stacktrace:
 [1] getproperty(x::Module, f::Symbol)
   @ Base ./Base.jl:42
 [2] top-level scope
   @ ~/.julia/packages/GeometryOps/4octE/src/types.jl:34
 [3] include(mod::Module, _path::String)
   @ Base ./Base.jl:557
 [4] include(x::String)
   @ GeometryOps ~/.julia/packages/GeometryOps/4octE/src/GeometryOps.jl:3
 [5] top-level scope
   @ ~/.julia/packages/GeometryOps/4octE/src/GeometryOps.jl:37
 [6] include
   @ ./Base.jl:557 [inlined]
 [7] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2881
 [8] top-level scope
   @ stdin:6
in expression starting at /Users/milan/.julia/packages/GeometryOps/4octE/src/types.jl:34
in expression starting at /Users/milan/.julia/packages/GeometryOps/4octE/src/GeometryOps.jl:3
in expression starting at stdin:6
  ✗ GeometryOps
  0 dependencies successfully precompiled in 3 seconds. 56 already precompiled.

ERROR: The following 1 direct dependency failed to precompile:

GeometryOps

@asinghvi17
Copy link
Member Author

Ah, you need to add GeometryOpsCore on this branch as well

If you have it dev'ed, dev ~/.julia/dev/GeometryOps/GeometryOpsCore should do it

@milankl
Copy link
Member

milankl commented Mar 27, 2025

This seems to work 🥳 @simone-silvestri

image

and quick check whether it's conserving

image

looks pretty good I would say!!!

@milankl
Copy link
Member

milankl commented Mar 27, 2025

With some combinations of grids and resolutions, e.g.

grid1 = randn(OctaHEALPixGrid, 24)
grid2 = randn(OctaminimalGaussianGrid, 12)

I'm hitting an error though

┌ Error: Intersection failed!
│   i1 = 1152
│   i2 = 289
└ @ Main In[135]:25

BoundsError: attempt to access 4-element Vector{GeometryOps.PolyNode{Float64}} at index [6]

Stacktrace:
  [1] throw_boundserror(A::Vector{GeometryOps.PolyNode{Float64}}, I::Tuple{Int64})
    @ Base ./essentials.jl:14
  [2] getindex
    @ ./essentials.jl:916 [inlined]
  [3] _classify_crossing!(alg::GeometryOps.FosterHormannClipping{GeometryOpsCore.Planar, GeometryOps.AutoAccelerator}, ::Type{Float64}, a_list::Vector{GeometryOps.PolyNode{Float64}}, b_list::Vector{GeometryOps.PolyNode{Float64}}; exact::GeometryOpsCore.True)
    @ GeometryOps ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/clipping_processor.jl:623
  [4] _classify_crossing!
    @ ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/clipping_processor.jl:606 [inlined]
  [5] _build_ab_list(alg::GeometryOps.FosterHormannClipping{GeometryOpsCore.Planar, GeometryOps.AutoAccelerator}, ::Type{Float64}, poly_a::GeoInterface.Wrappers.LinearRing{false, false, Vector{Tuple{Float64, Float64}}, Nothing, Nothing}, poly_b::GeoInterface.Wrappers.LinearRing{false, false, Vector{Tuple{Float64, Float64}}, Nothing, Nothing}, delay_cross_f::typeof(GeometryOps._inter_delay_cross_f), delay_bounce_f::typeof(GeometryOps._inter_delay_bounce_f); exact::GeometryOpsCore.True)
    @ GeometryOps ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/clipping_processor.jl:149
  [6] _build_ab_list
    @ ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/clipping_processor.jl:143 [inlined]
  [7] _intersection(alg::GeometryOps.FosterHormannClipping{GeometryOpsCore.Planar, GeometryOps.AutoAccelerator}, ::GeometryOpsCore.TraitTarget{GeoInterface.PolygonTrait}, ::Type{Float64}, ::GeoInterface.PolygonTrait, poly_a::GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{Tuple{Float64, Float64}}, Nothing, Nothing}}, Nothing, Nothing}, ::GeoInterface.PolygonTrait, poly_b::GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{Tuple{Float64, Float64}}, Nothing, Nothing}}, Nothing, Nothing}; exact::GeometryOpsCore.True, kwargs::@Kwargs{})
    @ GeometryOps ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/intersection.jl:86
  [8] _intersection
    @ ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/intersection.jl:76 [inlined]
  [9] #intersection#102
    @ ~/.julia/packages/GeometryOps/4octE/src/methods/clipping/intersection.jl:45 [inlined]
 [10] intersection

@asinghvi17
Copy link
Member Author

hmm, those look like this
iTerm2 omks7P

but computing the intersection seems to work fine for me manually.

@asinghvi17
Copy link
Member Author

asinghvi17 commented Mar 27, 2025

hmm - looks like this is an antimeridian cutting issue, this is the polygon from grid 2:
iTerm2 N3YLbB

edit: fixed

@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from c70fe68 to 7357b0d Compare April 3, 2025 20:10
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from 7357b0d to 584f594 Compare April 3, 2025 20:19
@asinghvi17 asinghvi17 changed the base branch from as/trees to graphite-base/283 April 4, 2025 02:24
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from 584f594 to 659d6b0 Compare April 4, 2025 02:25
@asinghvi17 asinghvi17 changed the base branch from graphite-base/283 to as/trees April 4, 2025 02:25
@simone-silvestri
Copy link

Hi @asinghvi17, when I try to use this branch in combination with ConservativeRegridding.jl I get the following error:

ERROR: The following 2 direct dependencies failed to precompile:

GeometryOps

Failed to precompile GeometryOps [3251bfac-6a57-4b6d-aa61-ac1fef2975ab] to "/Users/simonesilvestri/.julia/compiled/v1.10/GeometryOps/jl_BD8CaS".
ERROR: LoadError: UndefVarError: `CutAtAntimeridianAndPoles` not defined
Stacktrace:
 [1] top-level scope
   @ ~/.julia/packages/GeometryOps/LoXLj/src/transformations/correction/cut_at_antimeridian.jl:80
 [2] include(mod::Module, _path::String)
   @ Base ./Base.jl:495
 [3] include(x::String)
   @ GeometryOps ~/.julia/packages/GeometryOps/LoXLj/src/GeometryOps.jl:3
 [4] top-level scope
   @ ~/.julia/packages/GeometryOps/LoXLj/src/GeometryOps.jl:89
 [5] include
   @ ./Base.jl:495 [inlined]
 [6] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2292
 [7] top-level scope
   @ stdin:4
in expression starting at /Users/simonesilvestri/.julia/packages/GeometryOps/LoXLj/src/transformations/correction/cut_at_antimeridian.jl:53
in expression starting at /Users/simonesilvestri/.julia/packages/GeometryOps/LoXLj/src/GeometryOps.jl:3
in expression starting at stdin:4
ConservativeRegridding

Failed to precompile ConservativeRegridding [8e50ac2c-eb48-49bc-a402-07c87b949343] to "/Users/simonesilvestri/.julia/compiled/v1.10/ConservativeRegridding/jl_UH89QO".
ERROR: LoadError: UndefVarError: `CutAtAntimeridianAndPoles` not defined
Stacktrace:
 [1] top-level scope
   @ ~/.julia/packages/GeometryOps/LoXLj/src/transformations/correction/cut_at_antimeridian.jl:80
 [2] include(mod::Module, _path::String)
   @ Base ./Base.jl:495
 [3] include(x::String)
   @ GeometryOps ~/.julia/packages/GeometryOps/LoXLj/src/GeometryOps.jl:3
 [4] top-level scope
   @ ~/.julia/packages/GeometryOps/LoXLj/src/GeometryOps.jl:89
 [5] include
   @ ./Base.jl:495 [inlined]

@asinghvi17
Copy link
Member Author

asinghvi17 commented Apr 8, 2025

Ah my bad, looks like I pushed an incomplete change set. If you can go back one commit it should work, and I'll push a fix in half an hour or so.

@simone-silvestri
Copy link

No problem, no rush, I imagined you guys were still working on it 😄

@asinghvi17
Copy link
Member Author

OK this should work now!

@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from 32b860e to 9a9eb0a Compare April 16, 2025 20:38
@asinghvi17 asinghvi17 force-pushed the as/trees branch 2 times, most recently from 71b1953 to a801c2c Compare April 16, 2025 21:25
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch 2 times, most recently from 39294cc to f614a9f Compare April 16, 2025 21:32
@asinghvi17 asinghvi17 force-pushed the as/trees branch 2 times, most recently from 80fdae7 to 1f16564 Compare April 16, 2025 22:12
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch 2 times, most recently from 5f71566 to 3b35b5c Compare April 16, 2025 22:38
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from 3b35b5c to 8c9e10f Compare April 17, 2025 02:35
@asinghvi17 asinghvi17 marked this pull request as ready for review April 17, 2025 02:41
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from 8c9e10f to dc9536b Compare April 20, 2025 00:28
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from dc9536b to 9c409c3 Compare April 20, 2025 00:33
@asinghvi17 asinghvi17 force-pushed the as/trees-and-antimeridian branch from 9c409c3 to e54c0b4 Compare May 1, 2025 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants