Skip to content

Commit

Permalink
Handle NaNs when integrating
Browse files Browse the repository at this point in the history
NaNs are treated as zeros when integrating.
  • Loading branch information
ph-kev committed Oct 22, 2024
1 parent 34dc4e8 commit e33c854
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ if duplicate dates are detected.
- Fix issue with plotting multiple figures at the same time.
- Improve shading for `Visualize.heatmap2D_on_globe!`.
- Add support for automatically converting CFTime.AbstractCFDateTime dates to seconds.
- Treat `NaN`s as zeros when integrating (`integrate_lon, integrate_lat, integrate_lonlat`)

v0.5.10
-------
Expand Down
3 changes: 2 additions & 1 deletion src/Numerics.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Numerics

import ..Utils: _isequispaced
import NaNStatistics: nansum

"""
_integrate_lon(data::AbstractArray, lon::AbstractVector; dims)
Expand Down Expand Up @@ -67,7 +68,7 @@ function _integrate_over_angle(
size_to_reshape =
(i == angle_idx ? length(int_weights) : 1 for i in 1:ndims(data))
int_weights = reshape(int_weights, size_to_reshape...)
int_on_angle = sum(data .* int_weights, dims = angle_idx)
int_on_angle = nansum(data .* int_weights, dims = angle_idx)
return int_on_angle
end

Expand Down
6 changes: 6 additions & 0 deletions src/Var.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,8 @@ If the points are equispaced, it is assumed that each point correspond to the mi
cell which results in rectangular integration using the midpoint rule. Otherwise, the
integration being done is rectangular integration using the left endpoints for integrating
longitude and latitude. The units for longitude and latitude should be degrees.
All `NaN`s in `var.data` are treated as zeros when integrating.
"""
function integrate_lonlat(var::OutputVar)
var_integrate_lon = var |> integrate_lon
Expand All @@ -1150,6 +1152,8 @@ If the points are equispaced, it is assumed that each point correspond to the mi
cell which results in rectangular integration using the midpoint rule. Otherwise, the
integration being done is rectangular integration using the left endpoints. The unit for
longitude should be degrees.
All `NaN`s in `var.data` are treated as zeros when integrating.
"""
function integrate_lon(var::OutputVar)
has_longitude(var) || error("var does not has longitude as a dimension")
Expand All @@ -1167,6 +1171,8 @@ If the points are equispaced, it is assumed that each point correspond to the mi
cell which results in rectangular integration using the midpoint rule. Otherwise, the
integration being done is rectangular integration using the left endpoints. The unit for
latitude should be degrees.
All `NaN`s in `var.data` are treated as zeros when integrating.
"""
function integrate_lat(var::OutputVar)
has_latitude(var) || error("var does not has latitude as a dimension")
Expand Down
19 changes: 17 additions & 2 deletions test/test_Numerics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ end
dims = 1,
)

# Integrating only lon (non equispaced)
# Integrating only lon (equispaced)
lon = collect(range(-179.5, 179.5, 360))
lon_data = ones(length(lon))
@test isapprox(
Expand All @@ -101,7 +101,7 @@ end
atol = 0.01,
)

# Integrating only lat (non equispaced)
# Integrating only lat (equispaced)
lat = collect(range(-89.5, 89.5, 180))
lat_data = ones(length(lat))
@test isapprox(
Expand All @@ -110,4 +110,19 @@ end
atol = 0.01,
)

# Integrating with NaNs
lon = collect(range(-179.5, 179.5, 360))
lon_data = ones(length(lon))
lon_data[:] .= NaN
@test ClimaAnalysis.Numerics._integrate_lon(lon_data, lon, dims = 1)[1] ==
0.0

lon = collect(range(-179.5, 179.5, 360))
lon_data = ones(length(lon))
lon_data[1:180] .= NaN
@test isapprox(
ClimaAnalysis.Numerics._integrate_lon(lon_data, lon, dims = 1)[1],
1.0π,
atol = 0.01,
)
end

0 comments on commit e33c854

Please sign in to comment.