NEWS.md
wrap() is deprecated in favour of wrapTorus(), which does the same thing under a name that does not collide with terra::wrap() (an unrelated function that serialises a SpatRaster for saving). wrap() still works and redirects.transitions() is defunct. It was never fully implemented and there is no replacement; please contact the maintainer if you have a use for it.rndmPolygonSpatialPoints() and rndmPolygonSpatialPolygons() (already deprecated) now redirect to their SpatVector equivalents and convert the result back to sp, instead of carrying their own copies of the geometry code.SpatialPoints* object to crw() now warns. It is converted to a SpatVector on entry and converted back on return.spread2() now accepts a numeric vector for spreadProbRel, not just a raster. A raster spreadProbRel is re-materialised in full on every iteration in order to subset a handful of cells from it, which dominates runtime for callers that step one iteration at a time (iterations = 1L in a loop); passing a pre-materialised vector avoids this. Rasters and the scalar NA default are unaffected, and results are unchanged.adj() now delegates to terra::adjacent() for the 4-neighbour, 8-neighbour and bishop cases, including match.adjacent and include. This removes a large amount of duplicated neighbour-finding code. The torus case keeps its own integer arithmetic, which measured roughly 3x faster than routing it through wrapTorus().crw() handles sp input by converting it once on entry and converting back on return, rather than through a separate code path. See the bug fixes below for what that path had been doing.rings(returnDistances = FALSE) now writes the ring id into the returned raster. Both branches previously wrote distances, so the argument changed only the background value (0 rather than NA) and not the ring cells. Writing ids matches the allowOverlap = TRUE branch, which writes summed ids in the same situation, and matches the example in ?rings, which fills the raster with rngs$id by hand.heading() returned 0 instead of 180 for a due-south bearing. The quadrant corrections keyed off the sign of the x offset, which is zero due south, so neither correction applied; it now uses atan2(), which resolves all four quadrants directly.dwrpnorm2() failed for any mu longer than 1, with “argument is not numeric or logical”. A leftover line recycled a variable named var, which resolved to stats::var – the function, not a value.randomStudyArea(seed = ) did not restore the caller’s random number stream. It called set.seed() on the saved state vector, which takes a single number, so the stream was reseeded from that vector’s first element rather than restored.crw() given a SpatialPoints* object silently dropped the x1/y1 columns it documents (returning a SpatialPointsDataFrame with no columns), and returned a plain matrix rather than an sp object when that result was passed back in. Both are in the example in ?crw.move() checked for a NULL hypothesis after comparing it, so the check could never run: the comparison raised “argument is of length zero” first.crw() accepted a SpatVector of polygons and treated its vertices as agent positions. The guard meant to reject non-point geometries was nested inside a condition that could only be true when the object was not a SpatVector at all.numPerPatchMap example in specificNumPerPatch() remapped values in place, so later values could collide with ones already rewritten.terra needs), and per-branch build and coverage badges.spread() and spread2() are now faster: the per-iteration adj() call has been replaced with surgical Rcpp helpers (adjPairsMatrix() for spread(), adjPairsWithId() for spread2()) that compute neighbour pairs and apply edge filtering in C++. Output is value-identical to the previous implementation across a multi-seed verification battery (the pixels/initialPixels columns of spread2()’s data.table are now integer rather than numeric, but values are unchanged). Measured speedups: spread2 ~1.4×, spread ~1.6–2.3× depending on spreadProb and scenario.spread()’s no-flags branch (no id/returnIndices/circle/ relativeSpreadProb/neighProbs set, non-matrix path) also now goes through adjPairsMatrix() so the inner loop no longer calls adj().spread() and spread2(): each runs a parameter grid twice with the same seed and asserts bit-identical output.test-spread-snapshots.R): assert that spread() / spread2() output matches RDS snapshots captured from the pre-Rcpp baseline across 30 seeded scenarios (15 spread × 3 seeds and 16 spread2 × 3 seeds). Snapshots and the regeneration script live in tests/testthat/_spread_snapshots/.rasterizeReduced(): improved speed (#103). Benchmark on a 2000×2000 raster with 200 codes: single-column ~5× (0.65 s → 0.13 s), multi-column ~3.7× (0.69 s → 0.18 s).neutralLandscapeMap() now uses a built-in generator (type = "gaussian", the only supported type) that fills a padded grid with i.i.d. normal noise and smooths it with a square mean kernel, producing a roughly Gaussian random field. Use the new smooth argument to control autocorrelation length.NLMR-backed type values ("nlm_mpd", "nlm_gaussianfield", etc.) have been removed from neutralLandscapeMap(), and the NLMR dependency has been dropped entirely (removed from Suggests, Remotes, and Additional_repositories). The built-in "gaussian" generator replaces this functionality with no external dependency (PredictiveEcology/SpaDES.core#334).reproducible:::isGridded now exported as .isGridded (#99);rasterizeReduced();dqrng (#96; @rstub). if backwards compatibility is needed, set dqrng::dqRNGkind("Xoroshiro128+") before running spread to ensure numerical reproducibility with previous versions;randomPolygons() works with sf objects;crw to accommodate downstream dependency changes;splitRaster() tests that broke due to changes in reproducible::Filenames() (#91)quickPlot
crw to allow downstream packages that use matrix classes instead of sf or SpatVector classes for “agents”terra from raster and sp. Some functionality is available for sf, but this will not be complete.splitRaster() uses ".tif" as the default raster file typeterra::plot directly, but in a few cases, quickPlot::Plot is used as it is much better (e.g., spread2(plot.it = TRUE))reproducible supports R >= 4.1);terra to Importsmagrittr, rgeos, rlang, Require, graphics
Suggests: withr
quickPlot, fastmatch, raster, sp, sf, CircStats
snow to Suggests as it’s used for parallel raster operations;tools to Suggests for file.ext()
This is a major SpaDES.tools update causing breaking changes due to multiple CRAN packages no longer available as of R version 4.2 released April 2022.
ffbase and ff and deprecated use of lowMemory argument in spread (ffbase was removed from CRAN April 2022).RandomFields which is no longer maintained. We had to drop support for random landscape generation via gaussMap(); but see the NLMR package for tools to create random neutral landscapes.mergeRaster() can deal with rasters with different origins extents (i.e., that were not produced using splitRaster())spread2() causing failures on R-develsplitRaster() (#62; @anbm-dk)distanceFromEachPoint: cl argument can now accept a numeric scalar indicating how many cores to use with an mclapply internallydistanceFromEachPoint: minor speed improvementsspread3 has new arguments (sdDist, dispersalKernel)spread under most conditions, especially larger events, possibly up to 2x.splitRaster() can now specify file extension, instead of defaulting to .grd
We have identified a non-trivial bug in spread when using allowOverlap = TRUE. Until we can patch this bug, using this argument value will generate an error. We are currently working on a fix, which may take some time.
spread2 now takes a numeric for allowOverlap, to allow for 1 more scenario of overlapping, namely, allow between event overlapping, and within event overlapping only if the overlap occurs in the same iteration, otherwise, do not allow overlap within event.spread3 for simulating e.g., insect spreadpointDistance is now exportedrandomPolygon now has area argument, instead of hectares (deprecated), and it now succeeds for more cases.mergeRaster now accepts a function passed by the user when mosaic is triggered (#55, @tati-micheletti)initiateAgents example fixed to work with newer raster package versions (@rhijmans)splitRaster defaults to in-memory rasters when no file path specified (#47, @ianmseddy).gaussMap (#20, @ianmseddy).fastMask to reproducible packagefastCrop(): raster::crop is faster than velox::crop under many tests.fastMask(): moved to the reproducible package.randomPolygon function for single random polygon.spread2 when asymmetry used.A new package, which takes all auxiliary modelling functions out of the SpaDES package:
?SpaDES.tools::SpaDES.tools for an overview of included functionality.