1
1
export Climatology
2
2
3
+ checktranspose (A:: Matrix ):: Matrix = (size (A,1 ) > size (A,2 )) ? collect (transpose (A)) : A
4
+
3
5
function readgrid (fn, v):: Matrix
4
6
# read temperature file
5
7
X = ncread (fn, v)
6
8
# squash third dimension if necessary
7
- if ndims (X) > 2
8
- X = dropdims (X, dims= 3 )
9
+ d = ndims (X)
10
+ if d == 3
11
+ return checktranspose (dropdims (X, dims= 3 ))
12
+ elseif d == 2
13
+ return checktranspose (X)
9
14
end
10
- size (X, 1 ) > size (X, 2 ) ? collect ( transpose (X)) : X
15
+ error ( " unusual number of dimensions ( $d ) found in file $fn , variable $v " )
11
16
end
12
17
13
18
struct Climatology{𝒯}
@@ -73,14 +78,15 @@ function Climatology(fnr::String, #runoff file name
73
78
# discard nonsense
74
79
@. f[(f < 0 ) | (f > 1 )] = 0
75
80
76
- # demand everything is the same size
77
- @assert size (r) == size (T) == size (f)
78
- n, m = size (r)
79
-
80
81
# insist on the same types for grids
81
82
𝒯 = promote_type (eltype .((r, T, f))... )
82
83
r, T, f = convert .(Matrix{𝒯}, (r, T, f))
83
84
85
+ # demand everything is the same size
86
+ @assert size (r) == size (T) == size (f) " Climatology arrays must have the same size/shape"
87
+ n, m = size (r)
88
+ @assert length (lat) == n " latitude vector length ($(length (lat)) ) must match number of Climatology rows ($n )"
89
+
84
90
# make a mask from the non-NaN runoff values
85
91
mask = @. r |> isnan |> !
86
92
@@ -118,49 +124,51 @@ end
118
124
119
125
# --------------------------------------
120
126
121
- export landfraction, meanlandtemperature, meanlandrunoff, totallandrunoff
127
+ export landfraction
128
+ export meanlandtemperature
129
+ export meanlandrunoff, totallandrunoff
130
+ export meanlandlatitude
122
131
123
- # already exported in main file
124
- # landfraction(𝒸::Climatology) = sum(𝒸.f .* 𝒸.A)/sum(𝒸.A)
132
+ checkcut (cut) = @assert cut >= 0 " latitude cutoff must be positive"
133
+
134
+ checksize (n, m, X) = @assert size (X) == (n,m) " size mismatch between array and Climatology"
125
135
126
136
function landfraction (𝒸:: Climatology{𝒯} ; cut:: Real = Inf ) where {𝒯}
127
137
@unpack A, f, lat, n, m = 𝒸
128
- @assert cut >= 0
129
- L = zero (𝒯)
130
- S = zero (𝒯)
138
+ checkcut (cut)
139
+ @multiassign num, den = zero (𝒯)
131
140
@inbounds for i ∈ 1 : n, j ∈ 1 : m
132
141
if - cut <= lat[i] <= cut
133
- L += A[i,j]* f[i,j]
134
- S += A[i,j]
142
+ num += A[i,j]* f[i,j]
143
+ den += A[i,j]
135
144
end
136
145
end
137
- return L / S
146
+ return num / den
138
147
end
139
148
140
149
function landmean (X:: AbstractMatrix{𝒯} , 𝒸:: Climatology{𝒯} , cut:: Real = Inf ) where {𝒯}
141
150
@unpack mask, A, f, lat, n, m = 𝒸
142
- @assert size (X) == (n,m)
143
- @assert cut > 0
144
- s = zero (𝒯)
145
- a = zero (𝒯)
146
- @inbounds for i ∈ 1 : n, j ∈ 1 : m
151
+ checksize (n, m, X)
152
+ checkcut (cut)
153
+ @multiassign num, den = zero (𝒯)
154
+ for i ∈ 1 : n, j ∈ 1 : m
147
155
if mask[i,j] & (- cut <= lat[i] <= cut)
148
156
# land area of cell
149
157
LA = A[i,j]* f[i,j]
150
158
# contributions to averaging
151
- s += LA* X[i,j]
152
- a += LA
159
+ num += LA* X[i,j]
160
+ den += LA
153
161
end
154
162
end
155
- return s / a
163
+ return num / den
156
164
end
157
165
158
166
function landsum (X:: AbstractMatrix{𝒯} , 𝒸:: Climatology{𝒯} , cut:: Real = Inf ) where {𝒯}
159
167
@unpack mask, A, f, lat, n, m = 𝒸
160
- @assert size (X) == (n,m )
161
- @assert cut > 0
168
+ checksize (n, m, X )
169
+ checkcut ( cut)
162
170
s = zero (𝒯)
163
- @inbounds for i ∈ 1 : n, j ∈ 1 : m
171
+ for i ∈ 1 : n, j ∈ 1 : m
164
172
if mask[i,j] & (- cut <= lat[i] <= cut)
165
173
# land area of cell
166
174
LA = A[i,j]* f[i,j]
@@ -176,3 +184,5 @@ meanlandtemperature(𝒸::Climatology; cut::Real=Inf) = landmean(𝒸.T, 𝒸, c
176
184
meanlandrunoff (𝒸:: Climatology ; cut:: Real = Inf ) = landmean (𝒸. r, 𝒸, cut)
177
185
178
186
totallandrunoff (𝒸:: Climatology ; cut:: Real = Inf ) = landsum (𝒸. r, 𝒸, cut)
187
+
188
+ meanlandlatitude (𝒸:: Climatology ) = landmean (repeat (𝒸. lat, 1 , 𝒸. m), 𝒸)
0 commit comments