This is built with spread2 and is still experimental. This one differs from other attempts in that it treats the advection and dispersal as mathematical vectors that are added together. They are "rounded" to pixel centres.

spread3(start, rasQuality, rasAbundance, advectionDir, advectionMag,
  meanDist, plot.it = 2, minNumAgents = 50,
  verbose = getOption("LandR.verbose", 0), saveStack = NULL)

Arguments

start

Raster indices from which to initiate dispersal

rasQuality

A raster with habitat quality. Currently, must be scaled from 0 to 1, i.e., a probability of "settling"

rasAbundance

A raster where each pixel represents the number of "agents" or pseudo-agents contained. This number of agents, will be spread horizontally, and distributed from each pixel that contains a non-zero non NA value.

advectionDir

A single number or RasterLayer in degrees from North = 0 (though it will use radians if all values are abs(advectionDir) > 2 * pi). This indicates the direction of advective forcing (i.e., wind).

advectionMag

A single number or RasterLayer in distance units of the rasQuality, e.g., meters, indicating the relative forcing that will occur. It is imposed on the total event, i.e., if the meanDist is 10000, and advectionMag is 5000, then the expected distance (i.e., 63% of agents) will have settled by 15000 map units.

meanDist

A single number indicating the mean distance parameter in map units (not pixels), for a negative exponential distribution dispersal kernel (e.g., dexp). This will mean that 63 settled at this meanDist (still experimental)

plot.it

Numeric. With increasing numbers above 0, there will be plots produced during iterations. Currently, only 0, 1, or 2+ are distinct.

minNumAgents

Single numeric indicating the minimum number of agents to consider all dispersing finished. Default is 50

verbose

Numeric. With increasing numbers above 0, there will be more messages produced. Currently, only 0, 1, or 2+ are distinct.

saveStack

If provided as a character string, it will save each iteration as part of a rasterStack to disk upon exit.

Value

A data.table with all information used during the spreading

Examples

######################################################### # Simple case, no variation in rasQuality, numeric advectionDir and advectionMag ######################################################### library(raster) library(quickPlot) maxDim <- 10000 ras <- raster::raster(extent(c(0, maxDim, 0, maxDim)), res = 100, vals = 0) rasQuality <- raster(ras) rasQuality[] <- 1 rasAbundance <- raster(rasQuality) rasAbundance[] <- 0 # startPixel <- middlePixel(rasAbundance) startPixel <- sample(seq(ncell(rasAbundance)), 30) rasAbundance[startPixel] <- 1000 advectionDir <- 70 advectionMag <- 4 * res(rasAbundance)[1] meanDist <- 2600 if (interactive()) { # Test the dispersal kernel -- create a function plotDispersalKernel <- function(out, meanAdvectionMag) { out[, disGroup := round(distance / 100) * 100] freqs <- out[, .N, by = "disGroup"] freqs[, `:=`(cumSum = cumsum(N), N = N)] Plot(freqs$disGroup, freqs$cumSum, addTo = "CumulativeNumberSettled", title = "Cumulative Number Settled") # can plot the distance X number abline(v = meanAdvectionMag + meanDist) newTitle <- "Number Settled By Distance" Plot(freqs$disGroup, freqs$N, addTo = gsub(" ", "", newTitle), title = newTitle) # can plot the distance X number abline(v = meanAdvectionMag + meanDist) # should be 0.63: freqs[disGroup == meanAdvectionMag + meanDist, cumSum] / tail(freqs,1)[, cumSum] mtext(side = 3, paste("Average habitat quality: ", round(mean(rasQuality[], na.rm = TRUE), 2)), outer = TRUE, line = -2, cex = 2) } dev() # don't use Rstudio windows, which is very slow clearPlot() out <- spread3(rasAbundance = rasAbundance, rasQuality = rasQuality, advectionDir = advectionDir, advectionMag = advectionMag, meanDist = meanDist, verbose = 2, plot.it = 2) plotDispersalKernel(out, advectionMag) } ######################################################### ### The case of variable quality raster ######################################################### if (require(sf) && require(fasterize)) { library(SpaDES.tools) # for gaussMap a <- randomStudyArea(size = 1e9) ras <- raster(extent(a), res = 100) mask <- fasterize(st_as_sf(a), ras) # faster than raster::rasterize rasQuality <- gaussMap(ras) crs(rasQuality) <- crs(a) rasQuality[is.na(mask)] <- NA # rescale so min is 0.75 and max is 1 rasQuality[] <- rasQuality[] / (maxValue(rasQuality) * 4 ) + 1/4 rasAbundance <- raster(rasQuality) rasAbundance[] <- 0 startPixel <- sample(seq(ncell(rasAbundance)), 300) rasAbundance[startPixel] <- 1000 advectionDir <- 75 advectionMag <- 4 * res(rasAbundance)[1] meanDist <- 2600 clearPlot() out <- spread3(rasAbundance = rasAbundance, rasQuality = rasQuality, advectionDir = advectionDir, advectionMag = advectionMag, meanDist = meanDist, verbose = 2, plot.it = 1) if (interactive()) { plotDispersalKernel(out, advectionMag) } }
#> Loading required package: sf
#> Linking to GEOS 3.6.2, GDAL 2.2.3, PROJ 4.9.3
#> Loading required package: fasterize
#> #> Attaching package: ‘fasterize’
#> The following object is masked from ‘package:graphics’: #> #> plot
#> assuming that advectionDir is in geographic degrees(i.e., North is 0)
#> Iteration 1
#> Number still dispersing 218467.728350372
#> Iteration 2
#> Number still dispersing 217052.287599841
#> Iteration 3
#> Number still dispersing 214647.985352566
#> Iteration 4
#> Number still dispersing 211746.07336431
#> Iteration 5
#> Number still dispersing 209719.917583577
#> Iteration 6
#> Number still dispersing 207642.985655808
#> Iteration 7
#> Number still dispersing 204966.911057916
#> Iteration 8
#> Number still dispersing 203004.512786741
#> Iteration 9
#> Number still dispersing 200250.304543639
#> Iteration 10
#> Number still dispersing 197115.718376177
#> Iteration 11
#> Number still dispersing 193420.174278494
#> Iteration 12
#> Number still dispersing 189776.407211978
#> Iteration 13
#> Number still dispersing 186317.046739708
#> Iteration 14
#> Number still dispersing 183314.969329682
#> Iteration 15
#> Number still dispersing 180379.385112295
#> Iteration 16
#> Number still dispersing 177424.318374344
#> Iteration 17
#> Number still dispersing 174666.142014468
#> Iteration 18
#> Number still dispersing 171098.646840265
#> Iteration 19
#> Number still dispersing 167664.456651507
#> Iteration 20
#> Number still dispersing 164193.181754325
#> Iteration 21
#> Number still dispersing 161224.053369048
#> Iteration 22
#> Number still dispersing 157194.37762001
#> Iteration 23
#> Number still dispersing 153638.720896824
#> Iteration 24
#> Number still dispersing 149802.892949567
#> Iteration 25
#> Number still dispersing 146058.330199062
#> Iteration 26
#> Number still dispersing 142238.251942236
#> Iteration 27
#> Number still dispersing 139095.166881333
#> Iteration 28
#> Number still dispersing 135765.613716786
#> Iteration 29
#> Number still dispersing 131981.89735103
#> Iteration 30
#> Number still dispersing 128157.703989407
#> Iteration 31
#> Number still dispersing 124626.625676
#> Iteration 32
#> Number still dispersing 120454.202687023
#> Iteration 33
#> Number still dispersing 116667.229657478
#> Iteration 34
#> Number still dispersing 112462.841233291
#> Iteration 35
#> Number still dispersing 108224.772042226
#> Iteration 36
#> Number still dispersing 104658.269710226
#> Iteration 37
#> Number still dispersing 100738.193149239
#> Iteration 38
#> Number still dispersing 97379.7306585565
#> Iteration 39
#> Number still dispersing 93427.6810269982
#> Iteration 40
#> Number still dispersing 90442.7614934307
#> Iteration 41
#> Number still dispersing 87629.3054934393
#> Iteration 42
#> Number still dispersing 83998.1402508009
#> Iteration 43
#> Number still dispersing 80291.6109629692
#> Iteration 44
#> Number still dispersing 76939.9246709389
#> Iteration 45
#> Number still dispersing 73570.0029625303
#> Iteration 46
#> Number still dispersing 70570.6246272812
#> Iteration 47
#> Number still dispersing 66850.0452826847
#> Iteration 48
#> Number still dispersing 64081.1317406593
#> Iteration 49
#> Number still dispersing 60926.2940162978
#> Iteration 50
#> Number still dispersing 58413.9276578111
#> Iteration 51
#> Number still dispersing 55929.2494261002
#> Iteration 52
#> Number still dispersing 53053.9452422261
#> Iteration 53
#> Number still dispersing 50495.9962559369
#> Iteration 54
#> Number still dispersing 47132.8167978062
#> Iteration 55
#> Number still dispersing 44453.4488577386
#> Iteration 56
#> Number still dispersing 41846.2111409061
#> Iteration 57
#> Number still dispersing 39377.1733107536
#> Iteration 58
#> Number still dispersing 36874.8592082388
#> Iteration 59
#> Number still dispersing 34660.9514943397
#> Iteration 60
#> Number still dispersing 32316.6212929074
#> Iteration 61
#> Number still dispersing 30464.1994159539
#> Iteration 62
#> Number still dispersing 28091.8088630063
#> Iteration 63
#> Number still dispersing 26206.0469375026
#> Iteration 64
#> Number still dispersing 24169.1822807364
#> Iteration 65
#> Number still dispersing 22445.232356585
#> Iteration 66
#> Number still dispersing 21134.6840389676
#> Iteration 67
#> Number still dispersing 19448.560312541
#> Iteration 68
#> Number still dispersing 17715.8549636831
#> Iteration 69
#> Number still dispersing 15916.4776553081
#> Iteration 70
#> Number still dispersing 14560.9174690095
#> Iteration 71
#> Number still dispersing 13255.7118264949
#> Iteration 72
#> Number still dispersing 11535.3379619362
#> Iteration 73
#> Number still dispersing 10092.6649979768
#> Iteration 74
#> Number still dispersing 8971.92117765205
#> Iteration 75
#> Number still dispersing 8047.72642271128
#> Iteration 76
#> Number still dispersing 7455.71993251491
#> Iteration 77
#> Number still dispersing 6321.7851880863
#> Iteration 78
#> Number still dispersing 5711.40088272174
#> Iteration 79
#> Number still dispersing 5241.69485451169
#> Iteration 80
#> Number still dispersing 4214.80412479087
#> Iteration 81
#> Number still dispersing 3341.24918249259
#> Iteration 82
#> Number still dispersing 2721.61175553491
#> Iteration 83
#> Number still dispersing 2477.52214486491
#> Iteration 84
#> Number still dispersing 1505.84256424761
#> Iteration 85
#> Number still dispersing 44.3836898388998
############################################################################### ### The case of variable quality raster, raster for advectionDir & advectionMag ############################################################################### library(raster) library(quickPlot) library(SpaDES.tools) maxDim <- 10000 ras <- raster(extent(c(0, maxDim, 0, maxDim)), res = 100, vals = 0) rasQuality <- raster(ras) rasQuality[] <- 1 rasAbundance <- raster(rasQuality) rasAbundance[] <- NA # startPixel <- middlePixel(rasAbundance) startPixel <- sample(seq(ncell(rasAbundance)), 25) rasAbundance[startPixel] <- 1000 # raster for advectionDir advectionDir <- gaussMap(ras) crs(advectionDir) <- crs(rasQuality) # rescale so min is 0.75 and max is 1 advectionDir[] <- advectionDir[] / (maxValue(advectionDir)) * 180 # raster for advectionMag advectionMag <- gaussMap(ras) crs(advectionMag) <- crs(rasQuality) # rescale so min is 0.75 and max is 1 advectionMag[] <- advectionMag[] / (maxValue(advectionMag)) * 600 out <- spread3(rasAbundance = rasAbundance, rasQuality = rasQuality, advectionDir = advectionDir, advectionMag = advectionMag, meanDist = meanDist, verbose = 2, plot.it = 1)
#> assuming that advectionDir is in geographic degrees(i.e., North is 0)
#> Iteration 1
#> Number still dispersing 24951.7427882092
#> Iteration 2
#> Number still dispersing 24870.0592892225
#> Iteration 3
#> Number still dispersing 24735.2901165846
#> Iteration 4
#> Number still dispersing 24379.2168253953
#> Iteration 5
#> Number still dispersing 23775.9626226885
#> Iteration 6
#> Number still dispersing 23449.4662882185
#> Iteration 7
#> Number still dispersing 23145.3231817019
#> Iteration 8
#> Number still dispersing 22786.4827643283
#> Iteration 9
#> Number still dispersing 22380.7192873888
#> Iteration 10
#> Number still dispersing 21918.7232245054
#> Iteration 11
#> Number still dispersing 21444.2185104944
#> Iteration 12
#> Number still dispersing 20958.7930770182
#> Iteration 13
#> Number still dispersing 20417.7880405449
#> Iteration 14
#> Number still dispersing 19794.4378570753
#> Iteration 15
#> Number still dispersing 19197.9295114491
#> Iteration 16
#> Number still dispersing 18614.4961230115
#> Iteration 17
#> Number still dispersing 17989.9727064152
#> Iteration 18
#> Number still dispersing 17312.9851545405
#> Iteration 19
#> Number still dispersing 16640.8898334055
#> Iteration 20
#> Number still dispersing 16011.5099584516
#> Iteration 21
#> Number still dispersing 15389.3205122649
#> Iteration 22
#> Number still dispersing 14716.7330432009
#> Iteration 23
#> Number still dispersing 14092.2642130129
#> Iteration 24
#> Number still dispersing 13432.2816408026
#> Iteration 25
#> Number still dispersing 12795.0155873564
#> Iteration 26
#> Number still dispersing 12162.7012564564
#> Iteration 27
#> Number still dispersing 11551.251499279
#> Iteration 28
#> Number still dispersing 10952.0429879568
#> Iteration 29
#> Number still dispersing 10337.9391505125
#> Iteration 30
#> Number still dispersing 9764.88577808051
#> Iteration 31
#> Number still dispersing 9208.77724625343
#> Iteration 32
#> Number still dispersing 8651.84152402983
#> Iteration 33
#> Number still dispersing 8116.10154585853
#> Iteration 34
#> Number still dispersing 7593.03780155211
#> Iteration 35
#> Number still dispersing 7098.21054516305
#> Iteration 36
#> Number still dispersing 6626.15202287482
#> Iteration 37
#> Number still dispersing 6160.80239981882
#> Iteration 38
#> Number still dispersing 5721.19324986207
#> Iteration 39
#> Number still dispersing 5292.46228228828
#> Iteration 40
#> Number still dispersing 4896.76300051138
#> Iteration 41
#> Number still dispersing 4522.3623428805
#> Iteration 42
#> Number still dispersing 4159.27200905089
#> Iteration 43
#> Number still dispersing 3825.02769794956
#> Iteration 44
#> Number still dispersing 3504.01100696495
#> Iteration 45
#> Number still dispersing 3204.80955149448
#> Iteration 46
#> Number still dispersing 2922.41541536829
#> Iteration 47
#> Number still dispersing 2641.41071183887
#> Iteration 48
#> Number still dispersing 2392.98482631118
#> Iteration 49
#> Number still dispersing 2152.93973787239
#> Iteration 50
#> Number still dispersing 1929.37092674112
#> Iteration 51
#> Number still dispersing 1735.16507877662
#> Iteration 52
#> Number still dispersing 1556.594528115
#> Iteration 53
#> Number still dispersing 1392.21104477694
#> Iteration 54
#> Number still dispersing 1235.23863261621
#> Iteration 55
#> Number still dispersing 1088.65079044678
#> Iteration 56
#> Number still dispersing 954.38355272802
#> Iteration 57
#> Number still dispersing 845.183990026415
#> Iteration 58
#> Number still dispersing 741.43926547817
#> Iteration 59
#> Number still dispersing 652.035811256006
#> Iteration 60
#> Number still dispersing 567.471519172994
#> Iteration 61
#> Number still dispersing 495.641778597423
#> Iteration 62
#> Number still dispersing 430.641360455192
#> Iteration 63
#> Number still dispersing 374.895678032357
#> Iteration 64
#> Number still dispersing 319.694006577937
#> Iteration 65
#> Number still dispersing 268.519626575015
#> Iteration 66
#> Number still dispersing 216.955304209989
#> Iteration 67
#> Number still dispersing 170.405981460802
#> Iteration 68
#> Number still dispersing 132.501289549143
#> Iteration 69
#> Number still dispersing 101.555666681501
#> Iteration 70
#> Number still dispersing 76.8664574350437
#> Iteration 71
#> Number still dispersing 59.5411209954569
#> Iteration 72
#> Number still dispersing 43.0625433307432
if (interactive()) { dev() # don't use Rstudio windows, which is very slow clearPlot() Plot(advectionDir, title = "Wind direction", cols = "Reds") Plot(advectionMag, title = "Wind speed", cols = "Blues") plotDispersalKernel(out, mean(advectionMag[])) Plot(rasAbundance, addTo = "rasAbundance", cols = "black", title = "") }
# NOT RUN { ######################################### # save iterations to a stack to make animated GIF ######################################## tmpStack <- raster::rasterTmpFile("stackToAnimate") out <- spread3(rasAbundance = rasAbundance, rasQuality = rasQuality, advectionDir = advectionDir, advectionMag = advectionMag, meanDist = 2600, verbose = 2, plot.it = 0, saveStack = tmpStack) ## This animates the series of images into an animated GIF if (require(animation)) { out2 <- raster::stack(tmpStack) gifName <- file.path(tempdir(), "animation.gif") saveGIF(interval = 0.1, movie.name = gifName, expr = { for (i in seq(numLayers(out2))) plot(out2[[i]]) }) } # }