Project

General

Profile

« Previous | Next » 

Revision 5326e348

Added by Jim Regetz about 13 years ago

  • ID 5326e348c68821d57764224c3dc24e809359d47c

revamped aspect/flowdir boundary assessments to use circular statistics

View differences:

terrain/flow/flow-assessment.R
1
# R code to plot latitudinal profiles of mean flow direction, along with
2
# both RMSE and correlation coefficients comparing fused layers with
3
# both the raw ASTER and with the Canada DEM
1
# R code to plot latitudinal profiles of (circular) mean flow direction,
2
# along with both RMSE and (circular) correlation coefficients comparing
3
# fused layers with both the raw ASTER and with the Canada DEM
4 4
#
5 5
# Jim Regetz
6 6
# NCEAS
7
# Created on 08-Jun-2011
8 7

  
9 8
library(raster)
9
library(circular)
10 10

  
11 11
datadir <- "/home/regetz/media/temp/terrain/flow"
12 12

  
13
# create function to recode values into degrees
13
# create function to recode terraflow SFD values into degrees, with
14
# 0=North and proceeding clockwise (this matches gdaldem's default
15
# azimuth output for aspect calculation)
14 16
recode <- function(r) {
15 17
    v <- values(r)
16 18
    v[v==0] <- NA
17
    v[v==1] <- 0
18
    v[v==2] <- 45
19
    v[v==3] <- 90
20
    v[v==4] <- 90
21
    v[v==8] <- 135
22
    v[v==16] <- 180
23
    v[v==32] <- 225
24
    v[v==64] <- 270
25
    v[v==128] <- 315
19
    v[v==1] <- 90  ## east
20
    v[v==2] <- 135
21
    v[v==4] <- 180  ## south
22
    v[v==8] <- 225
23
    v[v==16] <- 270  ## west
24
    v[v==32] <- 315
25
    v[v==64] <- 0  ## north
26
    v[v==128] <- 45
26 27
    r[] <- v
27 28
    return(r)
28 29
}
......
31 32
sfd.aster <- recode(raster(file.path(datadir, "aster_300straddle_sfd.tif")))
32 33
sfd.srtm <- recode(raster(file.path(datadir, "srtm_150below_sfd.tif")))
33 34
sfd.uncor <- recode(raster(file.path(datadir, "fused_300straddle_sfd.tif")))
34
#sfd.eramp <- recode(raster(file.path(datadir, "fused_300straddle_rampexp_sfd.tif")))
35
sfd.enblend <- recode(raster(file.path(datadir, "fused_300straddle_enblend_sfd.tif")))
35 36
sfd.bg <- recode(raster(file.path(datadir, "fused_300straddle_blendgau_sfd.tif")))
36 37
sfd.can <- recode(raster(file.path(datadir, "cdem_300straddle_sfd.tif")))
37 38

  
......
46 47
# plot latitudinal profiles of mean flow direction
47 48
#
48 49

  
49
par(mfrow=c(2,2), omi=c(1,1,1,1))
50
# simple helper function to calculate row-wise means using circular
51
# mean, patterned after circ.mean in the CircStats package
52
rowMeansC <- function(r1, na.rm=TRUE) {
53
    m1 <- as.matrix(r1)
54
    m1[] <- (m1 * pi)/180
55
    sinr <- rowSums(sin(m1), na.rm=na.rm)
56
    cosr <- rowSums(cos(m1), na.rm=na.rm)
57
    cmeans <- atan2(sinr, cosr)
58
    (cmeans * 180)/pi
59
}
50 60

  
51
ylim <- c(80, 280)
61
par(mfrow=c(2,2), omi=c(1,1,1,1))
62
ylim <- c(-180, 180)
52 63

  
53
plot(lats300, rowMeans(as.matrix(sfd.uncor), na.rm=TRUE), type="l",
64
plot(lats300, rowMeansC(sfd.can), type="l", yaxt="n",
54 65
    xlab="Latitude", ylab="Mean flow direction", ylim=ylim)
55
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="uncorrected")
66
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
67
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="Original DEMs")
68
lines(lats300, rowMeansC(sfd.aster), col="blue")
69
lines(lats150, rowMeansC(sfd.srtm), col="red")
70
legend("bottomright", legend=c("ASTER", "SRTM", "CDED"), col=c("blue",
71
    "red", "black"), lty=c(1, 1), bty="n")
56 72
abline(v=60, col="red", lty=2)
57 73
mtext(expression(paste("Latitudinal profiles of mean flow direction (",
58
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
74
    125*degree, "W to ", 100*degree, "W)")), adj=0, line=2, font=2)
59 75

  
60
plot(lats300, rowMeans(as.matrix(sfd.can), na.rm=TRUE), type="l",
76
#plot(lats300, rowMeans(as.matrix(sfd.uncor), na.rm=TRUE), type="l",
77
#    xlab="Latitude", ylab="Mean flow direction", ylim=ylim)
78
#text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="uncorrected")
79
#abline(v=60, col="red", lty=2)
80
#mtext(expression(paste("Latitudinal profiles of mean flow direction (",
81
#    125*degree, "W to ", 100*degree, "W)")), adj=0, line=2, font=2)
82

  
83
plot(lats300, rowMeansC(sfd.uncor), type="l", yaxt="n",
61 84
    xlab="Latitude", ylab="Mean flow direction", ylim=ylim)
62
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="Canada DEM")
85
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
86
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="simple fused")
63 87
abline(v=60, col="red", lty=2)
64 88

  
65
#plot(lats300, rowMeans(as.matrix(sfd.eramp), na.rm=TRUE), type="l",
66
plot(lats300, rowMeans(as.matrix(sfd.can), na.rm=TRUE), type="n",
89
plot(lats300, rowMeansC(sfd.enblend), type="l", yaxt="n",
67 90
    xlab="Latitude", ylab="Mean flow direction", ylim=ylim)
68
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="exponential ramp")
69
text(mean(lats300), mean(ylim), pos=1, font=3, labels="(skipped)")
70
#abline(v=60, col="red", lty=2)
91
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
92
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="multires spline")
93
abline(v=60, col="red", lty=2)
71 94

  
72
plot(lats300, rowMeans(as.matrix(sfd.bg), na.rm=TRUE), type="l",
95
plot(lats300, rowMeansC(sfd.bg), type="l", yaxt="n",
73 96
    xlab="Latitude", ylab="Mean flow direction", ylim=ylim)
97
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
74 98
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="gaussian blend")
75 99
abline(v=60, col="red", lty=2)
76 100

  
77 101

  
102

  
78 103
#
79 104
# plot latitudinal profiles of RMSE
80 105
#
......
103 128
abline(v=60, col="red", lty=2)
104 129
mtext(expression(paste(
105 130
    "Flowdir discrepancies with respect to separate ASTER/SRTM components (",
106
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
131
    125*degree, "W to ", 100*degree, "W)")), adj=0, line=2, font=2)
107 132

  
108
#plot(lats300, rmse(sfd.eramp, sfd.aster), type="l", xlab="Latitude",
109
plot(lats300, rep(0, 300), type="n", xlab="Latitude",
133
plot(lats300, rmse(sfd.enblend, sfd.aster), type="l", xlab="Latitude",
110 134
    ylab="RMSE", ylim=ylim)
111
#lines(lats150, rmse(crop(sfd.eramp, extent(sfd.srtm)), sfd.srtm), col="blue")
112
#legend("topright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
113
#    lty=c(1, 1), bty="n")
135
lines(lats150, rmse(crop(sfd.enblend, extent(sfd.srtm)), sfd.srtm), col="blue")
136
legend("topright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
137
    lty=c(1, 1), bty="n")
114 138
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="exponential ramp")
115 139
text(mean(lats300), mean(ylim), font=3, labels="(skipped)")
116
#abline(v=60, col="red", lty=2)
140
abline(v=60, col="red", lty=2)
117 141

  
118 142
plot(lats300, rmse(sfd.bg, sfd.aster), type="l", xlab="Latitude",
119 143
    ylab="RMSE", ylim=ylim)
......
130 154
abline(v=60, col="red", lty=2)
131 155
mtext(expression(paste(
132 156
    "Flowdir discrepancies with respect to Canada DEM (",
133
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
157
    125*degree, "W to ", 100*degree, "W)")), adj=0, line=2, font=2)
134 158

  
135
#plot(lats300, rmse(sfd.eramp, sfd.can), type="l", xlab="Latitude",
136
plot(lats300, rep(0, 300), type="n", xlab="Latitude",
159
plot(lats300, rmse(sfd.enblend, sfd.can), type="l", xlab="Latitude",
137 160
    ylab="RMSE", ylim=ylim)
138 161
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="exponential ramp")
139 162
text(mean(lats300), mean(ylim), font=3, labels="(skipped)")
140
#abline(v=60, col="red", lty=2)
163
abline(v=60, col="red", lty=2)
141 164

  
142 165
plot(lats300, rmse(sfd.bg, sfd.can), type="l", xlab="Latitude",
143 166
    ylab="RMSE", ylim=ylim)
144 167
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="gaussian blend")
145 168
abline(v=60, col="red", lty=2)
146 169

  
170

  
171
#
172
# plot latitudinal profiles of correlation coefficients
173
#
174

  
175
# simple helper function to calculate row-wise *circular* correlation
176
# coefficients
177
corByLat <- function(r1, r2, rows) {
178
    if (missing(rows)) {
179
        rows <- 1:nrow(r1)
180
    }
181
    m1 <- circular(as.matrix(r1), units="degrees", rotation="clock")
182
    m2 <- circular(as.matrix(r2), units="degrees", rotation="clock")
183
    sapply(rows, function(row) {
184
        p <- cor.circular(m1[row,], m2[row,])
185
        if (is.null(p)) NA else p
186
        })
187
}
188

  
189
par(mfrow=c(2,3), omi=c(1,1,1,1))
190

  
191
ylim <- c(-1, 1)
192

  
193
# ...with respect to ASTER
194
plot(lats300, corByLat(sfd.uncor, sfd.aster), type="l", xlab="Latitude",
195
    ylab="Circular correlation", ylim=ylim)
196
lines(lats150, corByLat(crop(sfd.uncor, extent(sfd.srtm)), sfd.srtm), col="blue")
197
legend("bottomright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
198
    lty=c(1, 1), bty="n")
199
text(min(lats300), min(ylim), pos=4, font=3, labels="simple fused")
200
abline(v=60, col="red", lty=2)
201
mtext(expression(paste(
202
    "Flow direction correlations with respect to separate ASTER/SRTM components (",
203
    125*degree, "W to ", 100*degree, "W)")), adj=0, line=2, font=2)
204

  
205
plot(lats300, corByLat(sfd.enblend, sfd.aster), type="l", xlab="Latitude",
206
    ylab="Circular correlation", ylim=ylim)
207
lines(lats150, corByLat(crop(sfd.enblend, extent(sfd.srtm)), sfd.srtm), col="blue")
208
legend("bottomright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
209
    lty=c(1, 1), bty="n")
210
text(min(lats300), min(ylim), pos=4, font=3, labels="multires spline")
211
abline(v=60, col="red", lty=2)
212

  
213
plot(lats300, corByLat(sfd.bg, sfd.aster), type="l", xlab="Latitude",
214
    ylab="Circular correlation", ylim=ylim)
215
lines(lats150, corByLat(crop(sfd.bg, extent(sfd.srtm)), sfd.srtm), col="blue")
216
legend("bottomright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
217
    lty=c(1, 1), bty="n")
218
text(min(lats300), min(ylim), pos=4, font=3, labels="gaussian blend")
219
abline(v=60, col="red", lty=2)
220

  
221
# ...with respect to CDEM
222
plot(lats300, corByLat(sfd.uncor, sfd.can), type="l", xlab="Latitude",
223
    ylab="Circular correlation", ylim=ylim)
224
text(min(lats300), min(ylim), pos=4, font=3, labels="simple fused")
225
abline(v=60, col="red", lty=2)
226
mtext(expression(paste(
227
    "Flow direction correlations with respect to Canada DEM (",
228
    125*degree, "W to ", 100*degree, "W)")), adj=0, line=2, font=2)
229

  
230
plot(lats300, corByLat(sfd.enblend, sfd.can), type="l", xlab="Latitude",
231
    ylab="Circular correlation", ylim=ylim)
232
text(min(lats300), min(ylim), pos=4, font=3, labels="multires spline")
233
abline(v=60, col="red", lty=2)
234

  
235
plot(lats300, corByLat(sfd.bg, sfd.can), type="l", xlab="Latitude",
236
    ylab="Circular correlation", ylim=ylim)
237
text(min(lats300), min(ylim), pos=4, font=3, labels="gaussian blend")
238
abline(v=60, col="red", lty=2)
239

  
147 240
# close pdf device driver
148 241
dev.off()

Also available in: Unified diff