reproducible 3.1.1.9000
June 18, 2026 · View on GitHub
- development version.
bug fixes
-
prepInputs()now establishes Google Drive auth with a verified fallback cascade instead of guessing from gargle options. For a configured identity it no longer assumes "an email is set" means it works; it authenticates and then probes the actual file (drive_get()), accepting an identity only when it can read that resource. Order: a token already loaded (manualdrive_auth()) wins; otherwise a configuredgargle_oauth_email(the user's personal Drive — common case), then a service-account JSON named byGOOGLEDRIVE_AUTH/GARGLE_SERVICE_ACCOUNT, then anonymous/public. A rung whose prerequisite is absent (no email option, no service-account file) is skipped; an identity that authenticates but cannot read the file is deauthorized before the next is tried, so a service-account token never poisons latergoogledrivecalls. Each trial is silent and non-interactive (no OAuth prompt mid-cascade); oneTrying …line per rung is emitted atverbose. This fixes a configured service account (often set globally in.Renvironfor a bucket or CI) shadowing the user's own files with a404 "File not found". -
cliCol()(used bymessageColoured()/messagePreProcess()) no longer errors with "non-character object(s)" when areproducible.messageColour*option holds a colour function (e.g.cli::col_red) rather than a colour-name string; such functions now pass through unchanged. -
Cache(useCloud = TRUE)no longer pages the entire cloud-cache Google Drive folder on every call.driveLs()filtered file names locally, so each lookup asked the API for the whole folder (for an accumulated cache that is thousands of files — "Files retrieved so far: 3500 ...") just to keep the handful sharing onecacheId. Because cache files are named<cacheId>..., the per-cacheIdlookup now pushes a server-sidename contains '<cacheId>'query togoogledrive::drive_ls(), so Drive returns only the relevant files. Listings whose filter is not a plain name prefix (e.g. the.dbFile.metadata sweep used byshowSimilaracross machines) fall back to the previous full listing. -
prepInputsCOG()(the COG/vsicurl/fast-path) now shows terra's native progress bar during the windowed remote read, which previously ran silently for minutes. The windowed crop is written through terra's block loop so the bar advances as remote tiles are fetched; it is shown only whenverbose > 0. -
A public Google Drive file could still launch an interactive OAuth prompt when a service account was configured via the
GOOGLEDRIVE_AUTHenvironment variable (or any case where "auth is configured" did not mean "auth will actually succeed silently"). The previous logic guessed from gargle options/env whether authentication was possible, then letdrive_get()attempt it — but plaindrive_auth()does not consultGOOGLEDRIVE_AUTH, so the guess was a false positive that fell through to the prompt.assessGoogle()now attempts authentication non-interactively instead of guessing: it tries theGOOGLEDRIVE_AUTH/GARGLE_SERVICE_ACCOUNTservice-account JSON, then a cached user token, withrlang_interactiveforcedFALSEso a missing token errors quietly rather than prompting; only if nothing usable loads does it deauthorize and read the public file anonymously. Net: a loaded or silently-loadable token (incl. a service account) is used; a public file always resolves with no prompt;reproducible.gdriveNoAuth = TRUEstill forces the public path. -
A regression in that no-prompt change: a user who had configured gargle auth (
gargle_oauth_emailset) but had not yet rundrive_auth()was silently downgraded to anonymous — the auth attempt forcedrlang_interactive = FALSEunconditionally, so with no cached token it failed quietly andassessGoogle()deauthorizedgoogledrive. That 404'd their private Drive files (e.g. a Drive folder, which has no public-mirror remap) and, becausedrive_deauth()is a global state change, poisoned later directgoogledrivecalls in the same session. Now the auth attempt only forces non-interactive when no auth is configured (the public-file case, which must never prompt); when a service account orgargle_oauth_emailis configured, the session's own interactivity is respected, so a missing token loads from cache or completes OAuth — no manualdrive_auth()step needed. -
A further case of that same regression: when a configured user's quiet auth attempt could not silently load a token — e.g. the cached token was minted with an OAuth client googledrive has since changed (
tidyverse-erato→tidyverse-clio), or the session is non-interactive —assessGoogle()still calleddrive_deauth()and read anonymously, 404ing their private file ("File not found") and poisoning latergoogledrivecalls..gdrivePrepareAuth()now deauthorizes only when auth is not configured (the public-file reader) orreproducible.gdriveNoAuth = TRUE. A configured user whose quiet attempt fails is left untouched, so the realdrive_get()/drive_download()runs its normal auth — completing OAuth in an interactive session, or raising gargle's clear "non-interactive auth" error instead of a misleading 404.
new features
-
reproducible.urlRemapmanifests may now carry an optionalidcolumn (the Google Drive file id; also accepted asgoogledriveId/googledrive_id/driveId/gid). It is used as a secondary match, by the id parsed from a Driveurl, when the resolved filename is unavailable — e.g. an unauthenticated session that cannot read a Drive file's metadata. With it, a Drive URL whose id is in the manifest is redirected to the (public) mirror byprepInputs()before the Drive metadata lookup, so the download needs no Google authentication at all. Manifests without anidcolumn are unchanged. -
reproducible.urlRemapmanifests may now carry an optionaltypecolumn ("file"/"dir") for directory remaps: a"dir"row maps a Google Drive folder id to a bucket prefix-listing URL (e.g.<base>/?prefix=<key>/&delimiter=/). WhenpreProcess()downloads such a folder, it enumerates the folder's files from that public S3 listing (parsed with base R, noxml2dependency) and downloads each from its mirror URL, instead ofgoogledrive::drive_ls()— so listing a Drive folder needs no authentication. The folder is also recognised as a directory from the manifest alone, avoiding thedrive_get()(auth) probe inisGoogleDriveDirectory().buckethost::makeMirrorManifest(directories = TRUE)emits such a manifest. Manifests without atypecolumn are unchanged.
bug fixes
-
The public-Drive no-auth metadata read no longer prevents a configured user from authenticating. The previous change deauthorized
googledrivewhenever no token was currently loaded, but "no token loaded" is not the same as "cannot authenticate": a user withgargle_oauth_email(+gargle_oauth_cache) set, or a service-account JSON, can load a cached token silently.assessGoogle()now only falls back to anonymous access when token-less and gargle has no usable non-interactive auth configured (sodrive_auth()can silently load the cached token);reproducible.gdriveNoAuth = TRUEstill forces anonymous. -
A failed Google Drive access during
prepInputs()/preProcess()now reports the full, browser-pasteable URL instead of only the barefileId. Previously agoogledrive::drive_get()failure surfaced e.g.File not found: 13-atqi_7ogRPIFxOoJZoUDYdQCJ5-a_u., which cannot be opened in a browser to check the file exists / is shared.assessGoogle()now wraps the metadata read and re-raises withhttps://drive.google.com/file/d/<id>(or the original Drive URL), keeping the underlying error detail (e.g. the 404 reason). -
A public Google Drive file no longer triggers an interactive OAuth prompt ("Is it OK to cache OAuth access credentials ...") during
prepInputs()/preProcess()when nogoogledrivetoken is loaded. The no-auth download path (added previously) was defeated by the metadata read inassessGoogle():googledrive::drive_get()with no cached token launches interactive OAuth even for an "Anyone with the link" file, and that read happens before the download.assessGoogle()now deauthorizesgoogledrivefor that read when there is no token (the typical "cloud reader" case) or whenreproducible.gdriveNoAuth = TRUE, so a public file's metadata resolves anonymously via an API key. A loaded token (a "cloud writer", who needs auth to write a shared cloud cache) is left intact; in the edge case ofgdriveNoAuth = TRUEwith a token present, the token is restored after the read.
new features
reproducible.urlRemapnow accepts the mirror manifest directly, not only a pre-built function. It may be set to afunction(url, filename)(as before, e.g. viamakeUrlRemap()), adata.framemanifest withfilename/urlcolumns, or a length-one character path/URL to a CSV with those columns. For thedata.frame/CSV formsreproduciblebuilds the remap function internally (once, then cached), so a novice can simply writeoptions(reproducible.urlRemap = read.csv("manifest.csv"))without callingmakeUrlRemap(). An invalid value is ignored with a warning, so it can never break a download.
bug fixes
-
File-backed objects (e.g. a
terraSpatRaster) are now restored portably when a cache entry is shared between machines or users (notably a cloud cache). A file-backed raster embeds an absolute path to its backing.tif; previously, when another user retrieved such an entry,Cache()tried to recreate that path on their machine — e.g.cannot create dir '/home/<producer>' ... Operation not supportedfollowed by[rast] file does not exist. Three defects in the existing relative-path machinery caused this:relativeToWhat()used an inverted "is the file under this anchor?" test (so a raster even one directory below the working directory was stored with its absolute path);unwrapSpatRaster()reused the producer's embedded path on the normal load path instead of the stored relative tags; andremapFilenames()had no safe fallback for an unresolved/absolute path. Now the backing file is stored relative to the most specific matching anchor and rebuilt under the receiver's anchor of the same name; when no anchor resolves, the object is made self-contained under the receiver'scachePathrather than the producing machine's absolute path. -
New option
reproducible.fileBackedAnchors— a named list of project "anchor" directories (e.g. SpaDESpaths(sim)) consulted at both cache save and load so file-backed objects can be stored relative to a semantic, machine-independent anchor (e.g.inputPath) and restored to the equivalent location on another machine. See?reproducibleOptions. -
getRelative()no longer returns"NA/<basename>"when a path is (or is fully contained in)relativeToPath; it now correctly returns".". The old result came from(max(id) + 1):length(a)counting backwards when the path matchedrelativeToPathexactly, producingfile.path(NA, last). This corrupted the relativized paths stored bySpaDES.core::saveSimList()and, now that file-backed objects anchor to those paths, would otherwise surface as anNApath segment when restoring a file-backed object.
new features
-
Google Drive files that are shared "Anyone with the link" can now be downloaded by
prepInputs()/preProcess()without authentication. This happens automatically in three cases: (1) the suppliedurlis the public web-download form (e.g.https://drive.google.com/uc?export=download&id=<ID>); (2) nogoogledrivetoken is loaded — in which case the file's metadata could only have been read anonymously, which is proof it is public, so the public endpoint is used silently instead of failing with a "no token" error; or (3) the new optionreproducible.gdriveNoAuthisTRUE. An authenticated download that fails (e.g. an expired token) also silently falls back to the public endpoint, surfacing the original auth error only if the file turns out not to be public. Large files that return Google's "can't scan for viruses" interstitial are handled by parsing and resubmitting the one-time confirm token. Authenticated workflows (token loaded) are unaffected. -
Download progress is now visible in non-interactive / logged sessions.
httr2::req_progress()draws a cli progress bar that is silent when!cli::is_dynamic_tty()(logged runs, CI, a SpaDESsimInit) and writes straight to the terminal, so a largepreProcess()/prepInputs()download there produced no output until it finished. In those sessions the single-stream download now streams the body itself (httr2::req_perform_connection()) and reports progress throughmessagePreProcess()-- e.g.downloaded 45 Mb / 320 Mb (14%) | 12 Mb/s-- which the calling app (e.g. SpaDES.core's logger) timestamps. The cadence is set by the new optionreproducible.downloadProgressInterval(default2seconds). In a dynamic terminal the native in-place cli bar is unchanged. -
New diagnostic option
reproducible.preDigestDump(andreproducible.preDigestDumpPattern) to dump the full element-by-elementpreDigest(name = hash) that produces eachCache()cacheId. UnlikeshowSimilar(closest prior call only),dryRun, orverbose, it covers everyCache()call -- including ones built deep inside other packages (e.g. SpaDES.core events) -- so two machines' dumps can bediffed to find exactly what splits acacheIdacross machines/OSs (e.g. a cloud cache that will not share).TRUEmessages each call's sorted list; a directory path writes onepreDigest_<functionName>[_<n>].txtper call. See?reproducibleOptions. -
showSimilar(thereproducible.showSimilaroption, also used by dev mode anddryRun) is now cloud-aware. WhenuseCloudis active,Cache()previously compared the current call only against the local cache, so similar artifacts cached by other machines sharing the samecloudFolderIDwere never reported. It now downloads the small per-cacheIdmetadata files (.dbFile.*) from the cloud folder, folds them into the local cache listing, and follows the normalshowSimilarpath. Only metadata files are fetched (not the cached objects),cacheIds already present locally are skipped, and each remote metadata file is itself wrapped inCache()(keyed by itscacheId) so the manyCache()calls in a single run (e.g. a module's.inputObjects) do not re-download the same.dbFilerepeatedly across calls or sessions. That memo lives in a dedicatedcloudMetasub-cache, so it does not bloat the main cache'sshowCache()scans. -
New option
reproducible.digestVersion— a single integer that selects thecacheId(digest) algorithm, replacing the per-version booleansreproducible.digestV3/reproducible.digestV4(which are still honoured whendigestVersionis unset). It defaults to4, a platform-stable digest ofsfandSpatVectorobjects: geometry is the numeric vertex matrix with coordinates rounded to a fixed precision (plus the geometry type), and attributes are kept in feature order with columns sorted locale-independently. The same vector data therefore produces the samecacheIdon Windows, macOS and Linux (digest version 3 could differ across operating systems, preventing shared/cloud caching of these objects), and ansfobject and itsSpatVectorequivalent now digest identically. Because version 4 is the new default, thecacheIdof everysf/SpatVectorobject differs from thereproduciblepackage v3.1.1 and earlier, so cached results that involved such objects are recomputed once under the new algorithm. Setoptions(reproducible.digestVersion = 3)to keep the previous behaviour and avoid that one-time invalidation. Requires the \pkg{terra} package. See thedigestVersionentry in?reproducibleOptionsfor the full list of versions. -
Digest version 4 also realizes "deferred-string" ALTREP character vectors before hashing, so character content digests identically regardless of its internal representation. A deferred string (e.g. produced by
rbind-ing many data.frames,as.character()of a factor, etc.) serializes differently from its realized form — and differently across R versions/platforms — which could give the same character content a differentcacheIdon, e.g., Linux vs Windows (seen as a module's parameter table splitting the.inputObjectscacheId). The realization is a no-op for already-materialized vectors, so existingcacheIds are unchanged. -
Downloads can now be transparently redirected to faster mirrors and fetched in parallel. Two cooperating, opt-in features:
- URL remap hook — a new option
reproducible.urlRemapaccepts a functionfunction(url, filename)that is consulted in the download path once the target filename is resolved (for Google Drive URLs, after thedrive_get()lookup). It may return an alternative URL to download from instead — typically a public mirror that supports HTTP Range requests. ReturningNULL/the original URL leaves behaviour unchanged, and a remap that errors is ignored (with a warning) so it can never break a download. A new exported helpermakeUrlRemap(manifest)builds such a function from adata.framewithfilenameandurlcolumns (matching on basename). This is the opt-in switch for the faster download path; with the defaultNULL, nothing changes. - Parallel ranged downloads — once opted in via
reproducible.urlRemap(with no remap set, downloads are always single-stream), a download that resolves to an HTTPS URL advertisingAccept-Ranges: bytesand larger thanreproducible.parallel.threshold(default 10 MiB) is fetched asreproducible.parallel.streams(default48L) concurrent byte-range requests viacurl, then reassembled. The result is byte-identical to a single-stream download, so checksums are unaffected. A part that drops mid-transfer is retried individually (not a full re-download); only if a part still cannot complete after a few attempts does it fall back transparently to a single stream (also when ranges are unsupported). Setreproducible.parallel.streams = 1Lto force single-stream downloads. On networks that shape bandwidth per-connection this is dramatically faster: in one test a 6.1 GB file dropped from ~75 minutes (single-stream) to ~2 minutes (48 streams from a Range-capable mirror).
- URL remap hook — a new option
-
prepInputs()andpreProcess()now keep a record of every file and web address (URL) they download. By default, each download is saved as a permanent note on the matching cache entry, which you can look up later withshowCache(userTags = "reproducible.url"). Setoptions(reproducible.urlLog = TRUE)to also keep an in-memory list for the current session, which you can read withprepInputsLog()and empty withclearUrlLog(). Setoptions(reproducible.urlLog = FALSE)to turn the recording off. See?prepInputsLogand?reproducibleOptions.
behaviour changes
-
postProcessTo()is now faster and uses less memory on large rasters. A new optionreproducible.terraMemmax(default2, in GB) sets how much memoryterrais allowed to use per raster during the call; the previous setting is restored when the call finishes. In one test with a 1.8-billion-cell output, this was about 45% faster and used about one-third of the memory of the previous default. Set the option toNULLto turn the cap off. If you have already setterraOptions(memmax)yourself, that setting is left alone. -
postProcessTo()now keeps categorical (factor) rasters categorical. When the input is a factor raster and you have not suppliedmethodordatatype, the projection step uses nearest-neighbour (so no in-between values are invented) and the output is written with the same data type as the input (for example,INT1UstaysINT1Uinstead of being promoted toFLT4S, which would make the file four times larger and lose the link to the category labels). Anything you pass formethodordatatypeis respected as before. -
options("reproducible.gdalwarp")is removed. The option was a switch for an experimental alternative dispatch inpostProcessTo()that usedsf::gdal_utils("gdalwarp")directly. The branch behind the switch had been fully commented out for some time; the live code path was the same whether the option wasTRUEorFALSE. Any existingoptions(reproducible.gdalwarp = ...)calls in user code are now silently ignored and can be deleted.options("reproducible.gdalwarpThreads")(the unrelated thread-count knob fordetectThreads()) is unaffected. -
options("reproducible.cachePath")is no longer pre-set to a session-tempdir path when the package is loaded; the default is nowNULL. The first call to a user-facing entry point (Cache(),clearCache(),showCache(),keepCache(), ...) resolves it lazily via.checkCacheRepo(). If still unset at that point, the option is set to.reproducibleTempCacheDir()for the rest of the session. This lets project-setup layers (e.g.SpaDES.project::setupProject()) detect "unset" cleanly and stops every R session from silently committing to a non-persistent tempdir cache. Users who setoptions(reproducible.cachePath = ...)explicitly (in their.Rprofile, in a setup script, or viawithr::local_options()) see no change. -
options("reproducible.timeout")default raised from1200(20 min) to12000(~3.3 h). The previous default caused failures on large (multi-GB) downloads over slow or congested links well before the transfer could complete; the new default keeps the same wall-clock safety net but at a scale appropriate for the file sizes typically handled byprepInputs/preProcess. Users who setoptions(reproducible.timeout = ...)explicitly see no change.
bug fixes
-
A best-effort cloud cache upload no longer aborts the run. When caching an object whose stored form does not include every file
CacheStoredFile()predicts fromFilenames()(e.g. a cachedsimListthat references itsSpatRasterbackends rather than copying them under thecacheId),cloudUploadFromCache()previouslystop()ed with "File(s) to upload are not available" -- crashing a long, already-locally-saved run during the upload step. It now uploads the files that are present, warns about any it skips, and never errors (the local cache is intact regardless). -
The single-stream
preProcess/prepInputsdownload no longer hangs for hours on a slow or flaky connection. It was setting curl'sconnecttimeout(the cap on establishing a connection) toreproducible.timeout— the overall download budget, which defaults to12000seconds (3.3 h). A stalled TLS handshake (e.g. a transientSSL_connectfailure toopendata.nfis.org) therefore froze the session for many minutes before erroring. The connect timeout is now a short, dedicated cap, new optionreproducible.connecttimeout(default30Lseconds), mirroringreproducible.parallel.connecttimeoutfor the parallel ranged path;reproducible.timeoutstill governs the overall download. -
Parallel ranged downloads are now used only for URLs that the
reproducible.urlRemaphook actually redirected to a mirror, matching the documented intent. Previously, once a remap hook was set, the parallel path engaged for any range-capable URL — including direct origin servers that were never redirected. Some such servers (e.g.opendata.nfis.org) cap concurrent connections per IP, so most of the parallel streams stalled with 0 bytes and timed out, making the download far slower than a single stream before eventually falling back. Two changes: (1) a non-redirected URL now downloads single-stream directly; (2) a redirected mirror that nonetheless caps concurrency is detected on the first attempt and falls back to a single stream immediately instead of grinding through every retry. The new threshold for (2) isreproducible.parallel.minConcurrentFrac(default0.25;0disables it). -
Cloud caching no longer silently invents a Google Drive folder when none is specified. Previously,
Cache(useCloud = TRUE)with nocloudFolderID(and nooptions(reproducible.cloudFolderID)) derived a folder name from the local cache path and created/used it. That derived name differs from machine to machine, so two machines computing the identicalcacheIdeach read/write their own cloud folder and never share — the object is recomputed and re-uploaded on every machine, silently. Now:- if no
cloudFolderIDis set (neither the argument nor the option), cloud caching is skipped (local cache only) with a one-time message, since aNULLcloudFolderIDmeans "no cloud target", not "make one up"; - a
cloudFolderIDargument ofNULLnow falls back tooptions(reproducible.cloudFolderID)(the documented default) before this check, so a globally-set option is honoured; - when a
cloudFolderIDis supplied but cannot be resolved on Drive (not found, or not accessible to the authenticated account), a warning is now emitted (previously silent) explaining that the supplied folder was not used and how to fix it (pass the same accessible Drive folder id on every machine). To share a cloud cache across machines, set the same explicit folder on each, e.g.options(reproducible.cloudFolderID = googledrive::as_id("<id>")).
- if no
-
A direct
preProcess()call no longer prints the target/fun guessing messages ("targetFile was not specified...", "Tryingfunon ...", "More than one possible files to load... Picking the last one..."). BecausepreProcess()never loads the object into R (it only returns file paths), those messages were misleading. They are still shown whenpreProcess()is called fromprepInputs()(where a load follows) and are always suppressed whenfun = NA. The returnedtargetFile/funare unchanged. -
prepInputs/preProcessno longer error withmissing value where TRUE/FALSE neededin the remote hash check when the remote source advertises no file size (e.g. a server with nocontent-lengthheader). The size comparison now treats a missing remote size as "unknown" and falls through to the normal hash/download path. -
Parallel ranged downloads (the opt-in
reproducible.urlRemappath) no longer fail on Windows, where opening allreproducible.parallel.streams(e.g. 48) connections at once was refused at connection time, so almost every part failed and the download fell back to a single stream. The number of simultaneous connections is now capped (the file is still split into many small parts for cheap retries, but only some download at once); the new optionreproducible.parallel.maxConnectionscontrols this and defaults toparallelly::availableCores() - 1(orparallel::detectCores() - 1when the Suggestedparallellypackage is absent). The per-part failure reason (fromcurl) is now reported on each retry and on fallback, instead of being silently discarded. A new optionreproducible.parallel.connecttimeout(default30seconds) sets the per-connection establishment timeout; this was previously mis-derived fromreproducible.timeoutand could collapse to ~1 second if that option was lowered.
reproducible 3.1.1
bug fixes
- fixed a test failure (
test-destinationPathShared.R) on file systems whose inode numbers exceed.Machine$integer.max: the inode helper now compares inode numbers as strings rather than coercing to integer. No user-facing change; the package code is unaffected.
reproducible 3.1.0
new features
prepInputsCOG: new fast-path insideprepInputsfor remote tiled GeoTiff files (including Cloud Optimized GeoTiffs). When theurlis HTTP(S) and at least one ofto,cropTo, ormaskTois supplied, only the spatial window of interest is fetched via GDAL's/vsicurl/— no full-file download. The windowedSpatRasteris returned to the normalpostProcesspipeline for crop/mask/write. The fast-path can be disabled withoptions(reproducible.useCOG = FALSE).
enhancements
-
The options
reproducible.inputPathsandreproducible.inputPathsRecursivehave been renamed toreproducible.destinationPathSharedandreproducible.destinationPathSharedRecursiverespectively (matching theprepInputsnaming family). The old names remain fully functional as backwards-compatible aliases: ifreproducible.destinationPathSharedisNULLandreproducible.inputPathsis set, the old value is used automatically (with a deprecation message). Update your code by replacingoptions(reproducible.inputPaths = ...)withoptions(reproducible.destinationPathShared = ...)at your convenience. -
alsoExtractinprepInputs/preProcessnow accepts regex patterns in addition to exact filenames. For example,alsoExtract = "CMD_sm|CMD_sp"will extract all archive members whose name matches that regular expression. The expansion is performed against the archive's file listing usinggrep(): if an element is a literal match it is kept as-is; otherwise it is treated as a pattern. Special sentinel values ("similar","none",NA) are not affected. The expansion happens before file extraction whether or not the archive was already present before the call. -
preProcessnow skips downloading when a local copy already exists and matches the remote version, even if it was never recorded inCHECKSUMS.txtfor the currentdestinationPath. There is also a new<cacheId>.hashfile placed alongside the cached repository files, that is a simpler mechanism than theCHECKSUMS.txt, i.e., one file, one hash. This was implemented because there were too many edge cases that were difficult to handle when there is a singleCHECKSUMS.txtfile. Nevertheless, theCHECKSUMS.txtfile is still used if it is present, and the<>..hashfile is absent, so a user can manually place a knownCHECKSUMS.txtfile into a directory as "the canonical version". The newpp_remote_hash_checkstage fetches remote metadata (ETag / content-length for HTTP; md5Checksum / size for Google Drive) and compares against the local file. A stored.hashfile is checked first; if absent, file-size equality is used as a fast proxy and the hash is persisted for future runs. This fixes the common cluster pattern where an archive lives inoptions("reproducible.inputPaths")but has not yet been checksummed for the current run-specificdestinationPath.Design note — two-layer caching strategy: The remote hash check and the local
CHECKSUMS.txtare complementary, not competing. Remote metadata (ETags,content-length, Google Drivemd5Checksum) solves the bootstrapping problem — confirming a file is correct before it has ever been checksummed locally.CHECKSUMS.txtthen takes over for all subsequent runs: it requires no network round-trip, works on compute nodes without internet access, and is content-addressable (survives URL changes). Note that HTTP ETags are not universally content-hash-based — many servers derive them from inode + mtime, making cross-server or post-migration comparisons unreliable — so the remote check is intentionally a best-effort shortcut rather than a replacement for the local checksum record. -
showCache(when useDBI = FALSE) now has lazy memory caching. This is relevant for very large caches (e.g., >10,000 entries).Cache()now lazy-spawns theshowCacheasync background scan against the cachePath the call actually uses. With the lazy spawn, the firstCache()call insimInit/spadeskicks off the fork, which then runs to completion in parallel with the simulation; subsequentshowCache()calls return in ~1 second. The spawn helper is idempotent (~10 us per call). -
New exported helper
prepopulateCacheAsync(cachePath)lets workflows kick off the async scan explicitly (e.g. early insetupProject()) so the fork has even more wall-clock time to complete. -
Lots of new unit tests for new features, and to cover edge cases that were slipping through.
bug fixes
-
Cache(omitArgs = TRUE)now drops every captured argument from the cache digest, so the digest depends only onFUNitself (the function value -- including its body, so source edits still bust the cache) and.cacheExtra. Useful when a developer wants the cache key to be insensitive to the function's inputs and pin freshness via.cacheExtra(e.g. a quoted reference to runtime state) instead of enumerating every input or every argument to omit. Character-vectoromitArgs = c("a", "b")still works as before. -
downloadRemote: the "before" snapshot ofdestinationPathtaken before evaluatingdlFunnow usesrecursive = TRUEto match the "after" snapshot. Previously, the non-recursive snapshot omitted files that were already present in subdirectories ofdestinationPath, so thesetdiff()of after vs. before classified those pre-existing subdirectory files as newly created. They then propagated asdownloadResults$destFile, triggered the "already exists at. Use overwrite = TRUE?" stop later in the function, and surfaced as a confusing error mentioning unrelated stashed files (e.g. shapefile pieces extracted by an earlier prepInputscall into the samereproducible.inputPaths/reproducible.destinationPathShared). -
Cache(useCloud = ...)now accepts two character values, intended for separating developer and user roles when sharing a cloud-cache folder:"push"is equivalent toTRUE(developer role -- bidirectional; downloads on a cloud hit, uploads on a miss);"pull"is read-only (user role -- downloads on a cloud hit, never uploads). When"pull"is set and the local cache already has the object, the Google Drive listing is not fetched at all (the cloud is consulted only after a local miss). An invalid character value now errors at the front door ofCache()rather than silently being treated asFALSE. -
prepInputs/.guessAtTargetAndFun: no longer auto-selects OS-injected archive metadata whentargetFileis unspecified. Previously, a Mac-created zip containing bothfoo.shpand__MACOSX/._foo.shpcould pick the AppleDouble copy and fail to load. Filtering covers macOS (__MACOSX/*,._*AppleDouble,.DS_Store) and Windows (Thumbs.db,desktop.ini). An explicittargetFilepointing at one of these is still honored. -
pp_remote_hash_check: now skips URLs that are nothttp://orhttps://. Previously,file://URLs would attempt a HEAD-style metadata fetch and then callmakeRemoteHashFile, whose URL-to-filename mapping only strips thehttps?://prefix; on Windows the resulting.hashfilename retainedfile:and the drive-letter colon, which is not a legal Windows path character. -
prepInputs/preProcess: when called withdlFunonly (nourl,targetFile, orarchive), the file produced bydlFunis now treated as the source of truth. Previously,runChecksumswould still scangetOption("reproducible.inputPaths")and, with no canonical filename to look up,Checksums()listed every file in the stash and matched any of them against the stash'sCHECKSUMS.txt. A non-empty match silently redirecteddestinationPathto the stash and causedprepInputsto load an unrelated file (e.g., a previously stashed shapefile instead of the GADM.rdsproduced bygeodata::gadm()). -
prepInputs/preProcess:dlFun = pkg::fn(args)(a function call passed directly, withoutquote()-wrapping) is once again kept as a deferred call object instead of being eagerly evaluated. The previous fix fordlFun = if (cond) fn else NULLbroke this canonical usage by forcing the lazy promise for all non-quote()expressions. The new logic keeps function-call expressions (fn(args),pkg::fn(args),pkg:::fn(args)) deferred while still evaluating control-flow expressions and bare symbols. -
prepInputsCOGnow requires a GeoTiff-style URL extension (.tif,.tiff,.cog,.gtiff) before attempting a/vsicurl/read. Previously, any HTTP(S) URL combined with a spatial subsetting argument would trigger the fast-path, producing a confusingGDAL Error 4 ... not recognized as being in a supported file formatwarning when the URL pointed to an archive (e.g..zip,.tar.gz). -
lockFilenow usescheckPath(..., create = TRUE)instead of a silentdir.create(..., showWarnings = FALSE)when creating the lock-file directory, so a missing or unwritable cache directory (e.g., on a network filesystem) produces a clear error rather than a confusingfilelockfailure. -
Fix
.listFilesInArchiveincorrectly returning an empty file list for zip archives wherearchive::archive()reportssize = 0for every entry (a known metadata-reading issue with certain compression variants such as Deflate64). When all reported sizes are zero but the archive file itself is non-empty, all paths are now included rather than being filtered out. -
Fix spurious "More than one possible files to load" message (and "Picking the last one") printed by
preProcesseven whenfun = NA. When the user explicitly passesfun = NA(meaning: do not load the file into R),.guessAtTargetAndFunnow returns immediately without inspecting or messaging about the extracted file list. -
Fix
pp_remote_hash_checkincorrectly treating a direct.tif(or other non-archive) download as an archive when the remote hash matched. The stage was unconditionally settingctx$archive <- localFile, which caused downstreampp_extractto run7z/unzipon the plain raster file. Fix: only setctx$archivewhen.isArchive(localFile)is non-NULL. -
Fix spurious
preProcess could not extract the files from the archiveerror when files were already present on disk (e.g. extracted earlier in the same call or found viareproducible.inputPaths). InextractFromArchive,resultwas computed from the checkSums table before.checkSumsUpdate()was called, so freshly-extracted files had no prior entry andNROW(result) == 0forced the re-extraction branch even thoughall(isOK)was TRUE. Fix: computeresultafter.checkSumsUpdate()so it reflects current disk state. The error was non-fatal (caught by the surroundingtry()) but printed an alarming message and wasted effort attempting a zero-file extraction. -
Fix
Google Drive download failed: HTTP 401 Unauthorizederror that occurred mid-session when downloading multiple tiles viaprepInputsWithTiles. The rawaccess_tokenstring extracted from thegargle/googledrivetoken expired (1-hour TTL) while tiles were being downloaded. Fix: force a gargle token refresh (viaToken2.0$refresh()) before eachdownload_resumable_httr2call, and retry once on 401 with a fresh token for both the httr2 and curl code paths. -
Fix
object 'fun' not founderror whenCache(prepInputs, ..., fun = fun, ...)is called withfunas a local variable name.substitute(fun)captured the symbol rather than the value; the symbol was then evaluated in the wrong frame (Cache's internal frame, not the user's). Fix: force the R promise directly (funCaptured <- fun) so resolution happens in the frame where the promise was created (the user's frame), regardless of call depth. -
Fix
filelock::lock()"Permission denied" error under high parallelism (30+ workers). Three root causes: (1) deleting the.lockfile afterunlock()broke mutex correctness — workers blocked onfcntl(F_SETLKW)held the old inode's lock while a fresh caller created a new inode and acquired its own "lock" simultaneously; (2) stale.lockfiles owned by root (from a prior sudo/root run) causedEACCESatopen(O_RDWR|O_CREAT); (3) thetryCatchmatched on "Permission denied" which is locale-dependent (varies withLC_MESSAGES) — now matches on "Cannot open lock file" (filelock's fixed C-level prefix). Fix: stop deleting lock files after release; wrapfilelock::lock()intryCatchwith a 5-attempt retry loop; match on the locale-independent error prefix. -
postProcess: when 2 large polygon datasets were provided (from and to), the pre-cropping step failed as the buffer was not applied. This has been fixed and the buffer now scales with the size of the polygons.
reproducible 3.0.0
- the package
qsremoved as an option forCacheSaveFormat. The user can stay with declaringoptions(reproducible.CacheSaveFormat = "qs"), but it will useqs2.qsis being removed from CRAN; - MacOS: key fixes for paths that have created longstanding failures;
- clearing out of stale code due to Cache rewrite;
- numerous Issues addressed;
- fixes for vignettes on especially MacOS or older R with respect to
terra::projectissues; - improved handling of archives when e.g.,
archivepackage is not installed or is not able to deal with the compression algorithm (e.g., Deflate64 from Windows); showCachenow uses a custom memoising internally. Large Cache repositories (>500GB) were slow toshowCache. Because it is memoised, this only affects 2nd and subsequent calls in an R session. The first will still be slower.CacheGeohandles a few more cases;isGoogleDriveDirectoryhandles more cases correctly (i.e., works now if it is a Google ID);- minor methods changes e.g., .wrap and .unwrap get defaults for some arguments;
- near complete rewrite of
Cacheso it is simpler and more robust. The main function is now 200 lines, instead of almost 700; internals all cleaner and maintainable; - new option
reproducible.leaveOnDiskwhich is only relevant forpostProcesswith objects that are sometimes disk-backed and sometimes memory-based (likeSpatRasterorRaster). The defaultterraandrasterbehaviour (which creates unpredictable behaviour, with the transient compute context being the trigger for one behaviour or another) for these was creating unnecessarily slowpostProcessingby bringing the objects to memory, sometimes, and this in turn led to unnecessarily slowCachebehaviour becauseterra::wrapis very slow for largeSpatRasterobjects. See?reproducibleOptions; showCache(whenuseDBI()isFALSE) now uses a type of internal memoising, so it is much faster for large cache databases, after a first time called.- several formerly unexported functions have been converted to
dotfunctions and are now exported e.g., for use in other packages; - In addition to full rewrites, numerous simplifications throughout code that is still being used;
- There are sufficient changes to the digesting that a user's Cache repository will likely be all or mostly rerun with these package changes. These changes to digesting were required because of incomplete cases that were being missed (i.e., false positive or false negatives). See more details below;
- many internal changes in the
postProcesspipeline whereterrafunctions are used. Now all functions are memory-safe, so will not bring the data to memory; Cachepreviously would bring some objects to memory that don't need to, e.g.,SpatRasterfromterra. These are now left on disk, as part of theCachepipeline;prepInputsWithTiles: new function.prepInputscan now pass through a different sub-function,prepInputsWithTiles, which can deal with (i.e., upload and download) remote files that are tiled. See?prepInputsWithTiles;- new experimental feature:
cacheChaining; in cases where there are >1Cachecall within a single function, thecacheChainingwilldigestthe containing function (viasys.function(-1)) to determine whether it is stable between calls. If it is unchanged, then a series ofCachecalls can be eligible for chaining, meaning where each subsequentCachecall refrains from digesting an object that was the outcome of a priorCachecall, within the same -- and unchanged from the previous time -- function. This can dramatically speed up computations whenCacheneeds to digest large objects and thedigeststep takes a long time; - drop support for R 4.1 and 4.2;
- attribute that was named "call" has been changed to "callInCache" to avoid newly discovered collision with xgboost package that uses that attribute name;
- many minor bugfixes;
formatreplacescacheSaveFormatas an argument so individual Cache calls can switch backend; this can be useful when e.g.,qs(which tends to be faster and smaller files) does not work for all types of objects e.g.,xgboost.CacheGeoadded new cases that are able to be used.- many edge cases were found that were not correctly Cached. This resulted in 2 major changes:
- rewrite and simplification of
Cache; - modified
digestof the arguments. These changes are not backwards compatible. Details next.
- rewrite and simplification of
- Fixes to several ongoing "edge cases" that were difficult to address, mostly
focused around deeply nested objects
that are file-backed with pointers, such
terra::SpatRasterclass; digestchanges include the following fixes:CacheDigestwhich is used withinCachedid not digest the names of the list of arguments passed. This did not affect.robustDigestof a normal list, which keeps the names intact.- file-backed objects were not correctly unique in the cache as they did not have
the
cacheIdin the filename; now they will have thecacheIdprefixed on the file (so they sort alongside the main cache file). ThiscacheIdprefix is removed on recovery from the cache, overwriting any files with the same name. - extracting the
functionNamefrom a function had several edge cases did not work; these now work
- To maintain as much compatibility with an other Cache database, while losing the more accurate digesting,
a user can set
options(reproducible.digestV3 = FALSE). This will keep the behaviour where lists are digested without their names forCacheDigestandCache. This will not affect the file-backed objects changes described above, which will ignore this option. useMemoisewould work with file-backed objects, but only if the file-backed object did not change after the caching (the pointer to the file was intact, but the file changed). Now, memoising will copy file-backed information from disk each time it "retrieves a file-backed object from memory". This will result in slower memoising than previously. However, it will be robust to downstream changes to the file.- new function
purgeChecksumsto allow user to manually purge a file from CHECKSUMS.txt - new options to help with backwards compatibility:
reproducible.useCacheV3: default = TRUE to use the new Cache source codereproducible.digestV3: default = TRUE to use the new Cache digest algorithms
maskTocan now use aSpatRasterfor the mask- minor bugfixes
reproducible 2.1.2
- remove
PackedStatExtentclass, releasing it forterra;reproduciblenow uses aPackedStatExtent2; this will eventually be replaced by theterraPackedStatExtentwhen this conflict is removed; .robustDigestmethod for"character"no longer will evaluate character strings as files, by default. A user can force the old behaviour withoptions(reproducible.testCharacterAsFile = TRUE)). This created unwanted, and inexplicable hanging of a computer, e.g., in adata.framewith thousands of rows of a character vector that represent filenames that existed, but their content was not expected to be digested; it would take possibly hours to digest. To digest files, user must explicitly coerce to"Path"withasPath(x), orfs::as_fs_pathas the previous hanging behaviour was surprising and could not be easily diagnosed;urlinprepInputscan now point to a directory; usealsoExtractto pick files by regular expression;- improved handling of symlinks in
remapFileNames(); - pass
terra::project()argumentsuse_gdalandby_utilthroughprojectTo()toterra::project(); - in some cases of downloading a file within
preProcess, supplying auser_agent(which happens automatically within the function) would cause the download to fail; now there is some redundancy withindlGenericthat will retry without auser_agentif it detects this issue;
Package dependency changes
- begin transition to use
cli; instead of custom messaging functions; - rm
crayondependency; - begin to replace
httr--> convert to usehttr2for some pieces; transition not complete;
Bugfix
- When forcing
cacheId, e.g., inCache(..., cacheId = "myCacheItem"),myCacheItemwas not used. Fixed. prepInputs(..., fun = sf::st_read)now works as expected ... likeprepInputs(..., fun = "sf::st_read")
reproducible 2.1.0
New
- new family of functions that are called inside
postProcessTothat usesf::gdal_utilsdirectly. These are still experimental and will only be activated withoptions("reproducible.gdalwarp" = TRUE) - default for
gdalMaskhas changed default for "touches". Now has equivalent forterra::mask(..., touches = TRUE), using"-wo CUTLINE_ALL_TOUCHED=TRUE" gdalProjectnow uses 2 threads, setting"-wo NUM_THREADS=2"; can be changed by user withoptions("reproducible.gdalwarpThreads" = X); see?reproducibleOptionsgdal*functions now addressdatatypeissuesgdal*defaults toFLT8Sifdatatypenot passedmakeRelative,makeAbsoluteand similar have been created to ease many issues encountered inpreProcess
Changes
showSimilar(e.g.,options(reproducible.showSimilar = 1)) now preferentially shows the most recent item in cache if there are several with equivalent matching.- overhaul of messaging in
CacheandprepInputsfamilies; functions are highlighted with a different colour; indent level reflects nesting of bothCacheandprepInputs, so it is easier to identify which message goes with which function call. preProcessis a lot faster now for large numbers of files; usesCHECKSUMSmore effectively and fewer timesretrynow captures itsexprso it doesn't need aquote; is liketrynow.showSimilarmechanisms now returns the most recent, if there are >1 similar that are equivalently similar- if a user is having troubles with
googledrivefor e.g., large files on spotting connections, instructions for usinggdownare provided showCache,clearCachenow have extra argumentsfun,cacheId, and...now can take any arbitrarytag = valuepair. ThecacheIdargument will be very fast if a user is not usinguseDBI()isFALSE..wrapand.unwrapcan now deal withSpatVectorCollection(aterraclass that does not have awrap/unwrapmethod interra)- ALTREP digesting when using
spookyorfastdigestwere not stable forintegersandfactors. There is now a work around in.robustDigestthat stabilizes these by expanding them from their ALTREP representation first. Since they will be saved and recovered anyway, this will have little effect. .wrapand.unwrapare becoming more mature and can handle many more classes effectively. Methods can still be written, if needed.
Testing
- lots of testing with
cacheSaveFormat = "qs", which previously was not reliable especially for environments. With all recent changes to.wrapand.unwrap, these appear stable now and should be able to be used forenvironments.
Bugfixes
switchDataTypecan now correctly switch betweengdalformats andterra- many messaging fixes that were imprecise or missing
reproducible 2.0.12
- re-submission after removal from CRAN
reproducible 2.0.11
Remove dependency
fastdigestwas removed from CRAN and so is removed from here.
reproducible 2.0.10
Bug fixes
- critical bugfixes for file-backed
SpatRasterobjects
reproducible 2.0.9
Enhancements
- new function
isUpdated()to determine whether a cached object has been updated; makeRelative()is now exported for use downstream (e.g.,SpaDES.core);- new functions
getRelative()andnormPathRel()for improved symlink handling (#362); - messaging is improved for
Cachewith the function named instead of justcacheId - messaging for
prepInputs: minor changes - more edge cases for
Checksumsdealt with, so fewer unneeded downloads wrapSpatRaster(wrapfor file-backedspatRasterobjects) fixes for more edge casespostProcessTocan now usesf::gdal_utilsfor the case offromis a gridded object andtois a polygon vector. This appears to be between 2x and 10x faster in tests.postProcessTodoes a pre-crop (with buffer) to make theprojectTofaster. When bothfromandtoare vector objects, this pre-crop appears to create slivers in some cases. This step is now skipped for these cases.Cachecan now deal with unnamed functions, e.g.,Cache((function(x) x)(1)). It will be refered to as "headless".terrawould fail if internet was unavailable, even when internet is not necessary, due to needing to retrieve projection information. Many cases where this happens will now divert to usesf.Cachecan now skip calculatingobjSize, which can take a non-trivial amount of time for large, complicated objects; seereproducibleOptions()
Bug fixes
Filenamesfor some classes returned ""; now returns NULL so character vectors are only pointers to files- Cache on a terra object that writes file to disk, when
quickargument is specified was failing, always creating the same object; fixed with #PR368 useDBIwas incorrectly used if a user had set the option prior to package loading. Now works as expected.- several other minor
preProcessdeals better with more cases of nested paths in archives.- more edge cases corrected for
inputPaths
reproducible 2.0.8
Enhancements
- minor formatting changes
- sometimes a cache entry gets corrupted. Previously, a message was supplied on how to fix; now this is just tried directly instead of just suggesting a user do it.
Bug fixes
- only use character strings when comparing
getRVersion() <= "XXX" - fixes for
assessDataTypefor categorical (factor)RasterandSpatRaster
reproducible 2.0.7
Enhancements
- Address change in
roundwithR > 4.3.1; now a primitive, that does method dispatch. Failure was identified with unit tests, by Luke Tierney who was making the change inbase::round.
Bug fixes
- several identified and fixed (PRs by Ceres Barros, notably, PRs #341, #342, #343). These fix missing argument in a
.unwrapcall, and missing check inpreProcess, whentargetFilePathwasNULL. - minor documentation updates
reproducible 2.0.5
Enhancements
- Updates of
Copy& new.wrap,.unwrapgenerics and methods to wrap classes that don't save well to disk as is. This uses the name similar toterra::wrap, but with slight differences internally to allow forSpatRasterobjects who are file-backed and must have their files moved when they are unwrapped. loadFilesupdated for more cases- convert to using
withrthroughout testing for cleaning up - more methods for
Filenameadded, including forPathclass Cache(..., useCloud = TRUE)had many cases that were not working; known cases are now working. Also, now file from file-backed cases are now placed inside thecacheOutputsfolder rather than inside a separate folder (used to be "rasters")
Bugfixes
- several small for edge cases
Dependency changes
- none
reproducible 2.0.4
Enhancements
reproducible.useFuturenow defaults to"multisession"- updated tests to deal with
data.tabledevelopment branch (#314) - removed all use of
data.table::setattrto deal with "modified compiler constants" issue that was detected during CRAN checks - Improvements with testing using GitHub Actions
Bugfixes
preProcessfailed whengoogledriveurl filename could be found, butdestinationPathwas not"."normPathhad different behaviour on *nix-alikes and Windows. Now it is the same.SpatRasterobjects if saved to a specific, non relative (togetwd()) path would not be recovered correctly (#316)- Several other Issues that addressed edge cases for
prepInputsand family.
reproducible 2.0.2
Enhancements
- new optional backend for
Cacheviaoptions(reproducible.useDBI = FALSE)is single data files with the samebasenameas the cached object, i.e., with the samecacheIdin the file name. This is a replacement forRSQLiteand will likely become the default in the next release. This approach makes cloud caching easier as all metadata are available in small binary files for each cached object. This is simpler, faster and creates far fewer package dependencies (now 11 recursive; before 27 recursive). If a user hasDBIandRSQLiteinstalled, then the backend will default to use these currently, i.e., the previous behaviour. The user can change the backend without loss of Cache data. - moved
rasterandsptoSuggests; no more internal functions use these. User can still work withRasterandspclass objects as before. preProcesscan now handle Google docs files, iftype = ...is passed.postProcessnow usesterraandsfinternally (with #253) throughout the family ofpostProcessfunctions. The previous*Inputand*Outputfunctions now redirect to the new*To*functions. These are faster, more stable, and cover vastly more cases than the previous*Inputsfamily. The old backends no longer work as before.- minor functions to assist with transition from
rastertoterra:maxFn,minFn,rasterRead .dealWithClassand.dealWithClassOnRecoveryare now exported generics, with several methods here, notably, list, environment, default- other miscellaneous changes to deal with
rastertoterratransition (e.g.studyAreaNamecan deal withSpatVector) prepInputsnow deals with archives that have sub-folder structure are now dealt with correctly in all examples and tests esp. #181.prepInputscan now deal with.gdbfiles. Though, it is limited tosfout of the box, so e.g., Raster layers insidegdbfiles are not supported (yet?). User can passfun = NAto not try to load it, but at least have the.gdbfile locally on disk.hardLinkOrCopynow useslinkOrCopy(symlink = FALSE); more cases dealt with especially nested directory structures that do not exist in theto.- many GitHub issues closed after transition to using
terraandsf. preProcesshad multiple changes. The following now work: archives with subfolders, archives with subfolders with identical basenames (different dirnames), gdb files, other files wheretargetFileis a directory.- ~40 issues were closed with current release.
- code coverage now approaching 85%
- substantial changes to
preProcessfor minor efficiency gains, edge cases, code cleaning - new function
CacheGeothat weaves togetherprepInputsandCacheto create a geo-spatial caching. See help and examples. maskTonow allowstouchesarg forterra::maskSpatialclass is also "fixed" infixErrorsInprepInputsandpreProcessnow capturedlFun, so user can pass unquoteddlFunCopymethod forSpatRaster, with and without file-backingCache(..., useCloud = TRUE)reworked so appears to be more robust than previously.maskTonow works even iftois larger thanfromnetCDFworks withprepInputs; thanks to user nbsmokee with PR #300.
Dependency changes
- no spatial packages are automatically installed any more; to work with
prepInputsand family, the user will have to installterraandsfat a minimum. terra,sfare inSuggests- removed entirely:
fasterize,fpCompare,magrittr - moved to
Suggests:raster,sp,rlang - A normal (minimal) install of
reproducibleno longer installsDBI, nor does it useRSQLite. All cache repositories database files will be in binary individual files in thecacheOutputsfile. If a user hasDBIand aSQLiteengine, then the previous behaviour will be used.
Defunct
reproducible.useNewDigestAlgorithmis not longer an option as the old algorithms do not work reliably.
Defunct and removed
- removed
assessDataTypeGDAL(),clearStubArtifacts(), - removed non-exported
digestRasterLayer2();evalArgsOnly();.getSourceURL();.getTargetCRS();.checkSums(),.groupedMessage();.checkForAuxililaryFiles() option("reproducible.polygonShortcut")removed
Non exported function changes
.basenamerenamed tobasename2
Bugfixes
Cachewas incorrectly dealing withenvironmentandenvironment-likeobjects. Since some objects, e.g.,Spat*objects interra, must be wrapped prior to saving, environments must be scanned for these classes of objects prior to saving. This previously only occurred forlistobjects;- When working with revdep
SpaDES.core, there were some cases where theCachewas failing as it could not find the module name; - during transition from
postProcess(usingrasterandsp) topostProcessTo, some cases are falling through the cracks; these have being addressed.
reproducible 1.2.16
Dependency changes
- none
Enhancements
Cachenow captures the first argument passed to it without evaluating it, soCache(rnorm(1))now works as expected.- As a result of previous,
Cachenow works with base pipe |> (with R >= 4.1). - Due to some internal changes in the way arguments are evaluated and digested, there may be some cache entries that will be rerun. However, in simple cases of
FUNpassed toCache, there should be no problems with previous cache databases being successfully recovered. - Added more unit tests
- Reworked
Cacheinternals so that digesting is more accurate, as the correct methods for functions are more accurately found, objects within functions are more precisely evaluated. - Improved documentation:
- Examples were reworked, replaced, improved;
- All user-facing exported functions and methods now have complete documentation;
- Added
()in DESCRIPTION for functions; - Added
\valuein.Rdfiles for exported methods (structure, the class, the output meaning); - Remove commented code in examples.
Bug fixes
postProcessnow also checks resolution when assessing whether to projectprepInputshas an internalCachecall for loading the object into memory; this was incorrectly evaluating all files if there were more than one file downloaded and extracted. This resulted in cases, e.g. shapefiles, being considered identical if they had the identical geometries, even if their data were different. This is fixed now as it uses the digest of all files extracted.
Deprecated and defunct
- remove defunct argument
digestPathContentfromCache options("reproducible.useGDAL")is now deprecated; the package is moving towardsterra.
reproducible 1.2.11
Dependency changes
- none
Enhancements
- none
Bug fixes
- fix tests for
postProcessToto deal with changes in GDAL/PROJ/GEOS (#253; @rsbivand) - fixed issue with masking
reproducible 1.2.10
Dependency changes
- Drop support for R 3.6 (#230)
- remove
gdalUtilities,gdalUtils, andrgeosfromSuggests - Added minimum versions of
rasterandterra, because previous versions were causing collisions.
Enhancements
- all direct calls to GDAL are removed: only
terraandsfare used throughout prepInputscan now takefunas a quoted expression onx, the object loaded bydlFuninpreProcesspreProcessargdlFuncan now be a quoted expression- changes to the internals and outputs of
objSize; now is primarily a wrapper aroundlobstr::obj_size, but has an option to get more detail for lists and environments. .robustDigestnow deals explicitly with numerics, which digest differently on different OSs. Namely, they get rounded prior to digesting. Through trial and error, it was found that settingoptions("reproducible.digestDigits" = 7)was sufficient for all known cases. Rounding to deeper than 7 decimal places was insufficient. There are also new methods forlanguage,integer,data.frame(which does each column one at a time to address the numeric issue)- New version of
postProcesscalledpostProcessTo. This will eventually replacepostProcessas it is much faster in all cases and simpler code base thanks to the fantastic work of Robert Hijmans (terra) and all the upstream work thatterrarelies on - Minor message updates, especially for "adding to memoised copy...". The three dots made it seem like it was taking a long time. When in reality, it is instantaneous and is the last thing that happens in the
Cachecall. If there is a delay after this message, then it is the code following theCachecall that is (silently) slow. retrycan now return a named list for theexprBetween, which allows for more than one object to be modified between retries.
Bug fixes
.robustDigestwas removing Cache attributes from objects under many conditions, when it should have left them there. It is unclear what the issues were, as this would likely not have impactedCache. Now these attributes are left on.data.tableobjects appear to not be recovered correctly from disk (e.g., from Cache repository. We have addeddata.table::copywhen recovering from Cache repositoryclearCacheandccdid not correctly remove file-backed raster files (when not clearing whole CacheRepo); this may have resulted in a proliferation of files, each a filename with an underscore and a new higher number. This fix should eliminate this problem.- deal with development versions of GDAL in
getGDALVersion()(#239) - fix issue with
maskInputs()when not passingrasterToMatch. - fix issue with
isna.SpatialFixwhen usingpostProcess.quosure
reproducible 1.2.8
Dependency changes
lwgeomnow a suggested package
Enhancements
terraclass objects can now be correctly saved and recovered byCachefixErrorscan now distinguishtestValidity = NAmeaning don't fix errors andtestValidity = FALSErun buffering which fixes many errors, but don't test whether there are any invalid polygons first (maybe slow), ortestValidity = TRUEmeaning test for validity, then if some are invalid, then run buffer.- Change default option to
reproducible.useNewDigestAlgorithm = 2which will have user visible changes. To keep old behaviour, setoptions(reproducible.useNewDigestAlgorithm = 1) - minor changes to messaging when
options(reproducible.showSimilar)is set. It is now more compact e.g., 3 lines instead of 5. - added
sfmethods tostudyAreaName
Bug fixes
- A small, but very impactful bug that created false positive
Cachereturns; i.e., a 2nd time through a Cache would return a cached copy, when some of the arguments were different. It occurred for when the differences were in unnamed arguments only.
reproducible 1.2.7
reproducible will be slowly changing the defaults for vector GIS datasets from the sp package to the sf package.
There is a large user-visible change that will come (in the next release), which will cause prepInputs to read .shp files with sf::st_read instead of raster::shapefile, as it is much faster. To change now, set options("reproducible.shapefileRead" = "sf::st_read")
Enhancements
- default
funinprepInputsfor shapefiles (.shp) is nowsf::st_readif the system hassfinstalled. This can be overridden withoptions("reproducible.shapefileRead" = "raster::shapefile"), and this is indicated with a message at the moment this is occurring, as it will cause different behaviour. quickargument inCachecan now be a character vector, allowing individual character arguments to be digested as character vectors and others to be digested as files located at the specified path as represented by the character vector.objSizepreviously included objects innamespaces,baseenvandemptyenv, so it was generally too large. Now uses the same criteria aspryr::object_size- improvements with messaging when
unzipmissing (thanks to @CeresBarros #202) - while unzipping, will also search for
7z.exeon Windows if the object is larger than 2GB, if can't findunzip. funargument inprepInputsand family can now be a quoted expression.archiveargument inprepInputscan now beNAwhich means to treat the file downloaded not as an archive, even if it has a.zipfile extension- many minor improvements to functioning of esp.
prepInputs - speed improvements during
postProcessespecially for very large objects (>5GB tested). Previously, it was running manyfixErrorscalls; now only callsfixErrorson fail of the proximate call (e.g., st_crop or whatever) retrynow has a new argumentexprBetweento allow for doing something after the fail (for example, if an operation fails, e.g.,st_crop, then runfixErrors, then return back tost_cropfor the retry)Cachenow has MUCH better nested levels detection, with messaging... and control of how deep the Caching goes seems good, via useCache = 2 will only Cache 2 levels in...archiveargument inprepInputsfamily can now be NA ... meaning do not try to unzip even if it is a.zipfile or other standard archive extensiongdb.zipfiles (e.g., a file with a .zip extension, but that should not be opened with an unzip-type program) can now be opened withprepInputs(url = "whateverUrl", archive = NA, fun = "sf::st_read")funargument inprepInputscan now be a quoted function call.preProcessnow does a better job with large archives that can't be correctly handled with the defaultzipandunzipwith R, by tryingsystem2calls to possible7z.exeor other options on Linux-alikes.
Bug fixes
Copygeneric no longer hasfileBackedDirargument. It is now passed through with the.... This was creating a bug with some cases wherefileBackedDirwas not being correctly executed.fixErrors()now better handlessfpolygons with mixed geometries that include points.- inadvertent deleting of file-backed rasters in multi-filed stacks during
Cache writeOutputs.Rasterattempted to changedatatypeofRasterclass objects using the setReplacementdataType<-, without subsequently writing to disk viawriteRaster. This created bad values in theRaster*object. This now performs awriteRasterif there is adatatypepassed towriteOutputse.g., throughprepInputsorpostProcess.updateSlotFilenamehas many more tests.prepInputs(..., fun = NA)now is the correct specification for "do not load object into R". This essentially replicatespreProcesswith same arguments.- several minor bugfixes
Copydid not correctly copyRasterStacks when some of theRasterLayerobjects were in memory, some on disk;raster::fromDiskreturnedFALSEin those cases, soCopydidn't occur on the file-backed layer files. UsingFilenamesinstead to determine if there are any files that need copying.
reproducible 1.2.6
Enhancements
- Optional (and may be default soon) -- An update to the internal digesting for file-backed Rasters that should be substantially faster, and smaller disk footprint. Set using
options("reproducible.useNewDigestAlgorithm" = 2) - changed default of
options("reproducible.polygonShortcut" = FALSE)as there were still too many edge cases that were not covered.
Bug fix
- fixed an error with rcnst on CRAN
RasterStackobjects with a single file (thus acting like aRasterBrick) are now handled correctly byCacheandprepInputsfamilies, especially with newoptions("reproducible.useNewDigestAlgorithm" = 2), though in tests, it worked with default alsoRSQLitenow uses a RNG duringdbAppend; this affected 2 tests (#185).
reproducible 1.2.4
Bug fix
- typo in date
reproducible 1.2.3
Bug fix
- minor url fix
reproducible 1.2.2
New features
- removed several uses of
rgeos - moved
paddedFloatToCharto reproducible from SpaDES.core. - increased code coverage
- Pull in legacy
%>%code frommagrittrto allow the cached alternative,%C%. With newmagrittrpipe now in compiled source code, more of the legacy code is required here.
Bug fixes
- several minor
reproducible 1.2.1
New features
- harmonized message colours that are use adjustable via options:
reproducible.messageColourPrepInputsfor allprepInputsfunctions;reproducible.messageColourCachefor allCachefunctions; andreproducible.messageColourQuestionfor questions that require user input. Defaults arecyan,blueandgreenrespectively. These are user-visible colour changes. - improved messaging for
Cachecases where afile.linkis used instead of saving. - with improved messaging, now
options(reproducible.verbose = 0)will turn off almost all messaging. postProcessand family now havefilename2 = NULLas the default, so not saved to disk. This is a change.verboseis now an argument throughout, whose default isgetOption(reproducible.verbose), which is set by default to1. Thus, individual function calls can be more or less verbose, or the whole session via option.
Bug fixes
RasterStackobjects were not correctly saved to disk under some conditions inpostProcess- fixed- several minor
reproducible 1.2.0
New features
postProcessnow uses a simpler single call togdalwarp, if available, forRasterLayerclass to accomplishcropInputs,projectInputs,maskInputs, andwriteOutputsall at once. This should be faster, simpler and, perhaps, more stable. It will only be invoked if theRasterLayeris too large to fit into RAM. To force it to be used the user must setuseGDAL = "force"inprepInputsorpostProcessor globally withoptions("reproducible.useGDAL" = "force")postProcesswhen using the newgdalwarp, has better persistence of colour table, and NA values as these are kept with better reliability- concurrent
Cachenow works as expected (e.g., with parallel processing, it will avoid collisions) with SQLite thanks to suggestion here: https://stackoverflow.com/a/44445010 - updated digesting of
Rasterclass objects to account for more of the metadata (including the colortable). This will change the digest value of allRasterlayers, causing re-run ofCache - removed
Require,pkgDep,trimVersionNumber,normPath,checkPaththat were moved toRequirepackage. For backwards compatibility, these are imported and reexported - address permanently or temporarily new changes in GDAL>3 and PROJ>6 in the spatial packages.
- new function
file.moveused to rename/copy files across disks (a situation wherefile.renamewould fail) - all
DBItype functions now have defaultcachePathofgetOption("reproducible.cachePath") Cache(prepInputs, ...on a file-backedRaster*class object now gives the non-Cache repository folder as thefilename(returnRaster). Previously, the return object would contain the cache repository as the folder for the file-backedRaster*
Dependency changes
- net reduction in number of packages that are imported from by 14. Removed completely:
backports,memoise,quickPlot,R.utils,remotes,tools, andversions; moved to Suggests:fastdigest,gdalUtils,googledrive,httr,qs,rgdal,sf,testthat; added:Require. Now there are 12 non-base packages listed in Imports. This is down from 31 prior to Ver 1.0.0.
bug fixes
- fix over-wide tables in PDF manual (#144)
- use
file.linknotfile.symlinkforsaveToCache. This would have resulted in C Stack overflow errors due to missing original file in thefile.symlink - use system call to
unzipwhen extracting large (>= 4GB) files (#145, @tati-micheletti) - several minor including
projectInputswhen converting to longlat projections,setMinMaxforgdalwarpresults Filenamesnow consistently returns a character vector (#149)- improvements to file-backed Raster caching to accommodate a few more edge cases
reproducible 1.1.1
New features
- none
Dependency changes
- none
bug fixes
- fix CRAN test failure when
file.linkdoes not succeed.
reproducible 1.1.0
New features
- begin to accommodate changes in GDAL/PROJ and associated updates to other spatial packages.
More updates are expected as other spatial packages (namely
raster) are updated. - can now change
options('reproducible.cacheSaveFormat')on the fly; cache will look for the file bycacheIdand write it usingoptions('reproducible.cacheSaveFormat'). If it is in another format, Cache will load it and resave it with the new format. Experimental still. - new
Copymethods forrefClassobjects,SQLiteand movedenvironmentmethod intoANYas it would be dispatched for unknown classes that inherit fromenvironment, of which there are many and this should be intercepted Requirecan now handle minimum version numbers, e.g.,Require("bit (>=1.1-15.2)"); this can be worked into downstream tools. Still experimental.- Cache will do
file.linkorfile.symlinkif an existing Cache entry with identical output exists and it is large (currently1e6bytes); this will save disk space. - Cache database now has tags for elapsed time of "digest", "original call", and "subsequent recovery from file",
elapsedTimeDigest,elapsedTimeFirstRun, andelapsedTimeLoad, respectively. - Better management of temporary files in package and tests, e.g., during downloading (
preProcess). Includes 2 new functions,tempdir2andtempfile2for use withreproduciblepackage - New option:
reproducible.tempPath, which is used for the new control of temporary files. Defaults tofile.path(tempdir(), "reproducible"). This feature was requested to help manage large amounts of temporary objects that were not being easily and automatically cleaned - Copying or moving of Cache directories now works automatically if using default
drvandconn; user may need to manually callmovedCacheif cache is not responding correctly. File-backed Rasters are automatically updated with new paths. - Cache now treats file-backed Rasters as though they had a relative path instead of their absolute path.
This means that Cache directories can be copied from one location to another and the file-backed
Raster*will have their filenames updated on the fly during a Cache recovery. User doesn't need to do anything. postProcessnow will perform simple tests and skipcropInputsandprojectInputswith a message if it can, rather than usingCacheto "skip". This should speed uppostProcessin many cases.- messaging with
Cachehas change. Now,cacheIdis shown in all cases, making it easier to identify specific items in the cache. - Automatically cleanup temporary (intermediate) raster files (with #110).
Dependency changes
- none
bug fixes
Copyonly creates a temporary directory for filebacked rasters; previously anyCopycommand was creating a temporary directory, regardless of whether it was neededcropInputs.spatialObjectshad a bug when object was a large non-Raster class.cropInputsmay have failed due to "self intersection" error when x was aSpatialPolygons*object; now catches error, runsfixErrorsand retriescrop. Great reprex by @tati-micheletti. Fixed in commit89e652ef111af7de91a17a613c66312c1b848847.Filenamesbugfix related toRasterBrickprepInputsdoes a better job of keeping all temporary files in a temporary folder; and cleans up after itself better.prepInputsnow will not show message that it is loading object into R iffun = NULL(#135).
reproducible 1.0.0
New features
- This version is not backwards-compatible out of the box. To maintain backwards compatibility, set:
options("reproducible.useDBI" = FALSE) - A new backend was introduced that uses
DBIpackage directly, withoutarchivist. This has much improved speed. - New option:
options("reproducible.cacheSaveFormat"). This can be eitherrds(default) orqs. All cached objects will be saved with this format. Previously it wasrda. - Cache objects can now be saved with with
qs::qsave. In many cases, this has much improved speed and file sizes compared tords; however, testing across a wide range of conditions will occur before it becomes the default. - Changed default behaviour for memoising
...becauseCacheis now much faster, the default is to turn memoising off, viaoptions("reproducible.useMemoise" = FALSE). In cases of large objects, memoising should still be faster, so user can still activate it, setting the option toTRUE. - Much better SQLite database handling for concurrent write attempts. Tested with dozens of write attempts per second by 3 cores with abundant locked database occurrences.
postProcessarguseGDALcan now take"force"as the default behaviour is to not use GDAL if the problem can fit into RAM andsforrastertools will be faster thanGDALtoolsuseCloudargument inCacheand family has slightly modified functionality (see ?Cache new sectionuseCloud) and now has more tests including edge cases, such asuseCloud = TRUE, useCache = 'overwrite'. The cloud version now will also follow the"overwrite"command.
Dependency changes
- deprecating
archivist; moved to Suggests. - removed imports for
bitops,dplyr,fasterize,flock,git2r,lubridate,RcppArmadillo,RCurlandtidyselect. Some of these went to Suggests.
bug fixes
postProcesscalls that use GDAL made more robust (including #93).- Several minor, edge cases were detected and fixed.
reproducible 0.2.11
Dependency changes
- remove
dplyras a direct dependency. It is still an indirect dependency throughDiagrammeR
New features
- new option:
reproducible.showSimilarDepthallows for a deeper assessment of nested lists for differences between the nearest cached object and the present object. This greater depth may allow more fine tuned understanding of why an object is not correctly caching - for downloading large files from GoogleDrive (currently only implemented), if user has set
options("reproducible.futurePlan")to something other thanFALSE, then it will show download progress if the file is "large".
bug fixes
- Several minor, edge cases were detected and fixed.
reproducible 0.2.10
Dependency changes
- made compatible with
googledrivev 1.0.0 (#119)
New features
pkgDep2, a new convenience function to get the dependencies of the "first order" dependencies.useCache, used in many functions (inclCache,postProcess) can now be numeric, a qualitative indicator of "how deep" nestedCachecalls should setuseCache = TRUE-- implemented as 1 or 2 inpostProcesscurrently. See?Cache
bug fixes
pkgDepwas becoming unreliable for unknown reasons. It has been reimplemented, much faster, without memoising. The speed gains should be immediately noticeable (6 second to 0.1 second forpkgDep("reproducible"))- improved
retryto use exponential backoff when attempting to access online resources (#121)
reproducible 0.2.9
New features
- Cache has 2 new arguments,
useCloudandcloudFolderID. This is a new approach to cloud caching. It has been tested with file backedRasterLayer,RasterStackandRasterBrickand all normal R objects. It will not work for any other class of disk-backed files, e.g.,fforbigmatrix, nor is it likely to work for R6 class objects. - Slowly deprecating cloudCache and family of functions in favour of a new approach using arguments to
Cache, i.e.,useCacheandcloudFolderID downloadDatafrom Google Drive now protects against HTTP2 error by capturing error and retrying. This is a curl issue for interrupted connections.
Bug fixes
- fixes for
rcnsterrors on R-devel, tested usingdevtools::check(env_vars = list("R_COMPILE_PKGS"=1, "R_JIT_STRATEGY"=4, "R_CHECK_CONSTANTS"=5)) - other minor improvements, including fixes for #115
reproducible 0.2.8
New features
- new functions for accessing specific items from the
cacheRepo:getArtifact,getCacheId,getUserTags retry, a new function, wrapstrywith an explicit attempt to retry the same code upon error. Useful for flaky functions, such asgoogldrive::drive_downloadwhich sometimes fails due tocurlHTTP2 error.- removed all
Rcppfunctionality as the functions were no longer faster than their R base alternatives.
Bug fixes
prepInputswas not correctly passinguseCachecropInputswas reprojecting extent of y as a time saving approach, but this was incorrect ifstudyAreais aSpatialPolygonthat is not close to filling the extent. It now reprojectsstudyAreadirectly which will be slower, but correct. (#93)- other minor improvements
reproducible 0.2.7
New features
CHECKSUMS.txtshould now be ordered consistently across operating systems (note:base::orderwill not succeed in doing this --> now using.orderDotsUnderscoreFirst)cloudSyncCachehas a new argument:cacheIds. Now user can control entries bycacheId, so can delete/upload individual objects bycacheId- Experimental support within the
postProcessfamily forsfclass objects
bug fixes
- mostly minor
cloudCachebugfixes for more cases
reproducible 0.2.6
Dependency changes
- remove
tibblefrom Imports as it's no longer being used
New features
- remove
%>%pipe that was long ago deprecated. User should use%C%if they want a pipe that is Cache-aware. See examples. - Full rewrite of all
optionsdescriptions now inreproducible, see?reproducibleOptions - now
cacheRepoandoptions("reproducible.cachePath")can take a vector of paths. Similar to how .libPaths() works for libraries,Cachewill search first in the first entry in thecacheRepo, then the second etc. until it finds an entry. It will only write to the first entry. - new value for the option:
options("reproducible.useCache" = "devMode"). The point of this mode is to facilitate using the Cache when functions and datasets are continually in flux, and old Cache entries are likely stale very often. IndevMode, the cache mechanism will work as normal if the Cache call is the first time for a function OR if it successfully finds a copy in the cache based on the normal Cache mechanism. It differs from the normal Cache if the Cache call does not find a copy in thecacheRepo, but it does find an entry that matches based onuserTags. In this case, it will delete the old entry in thecacheRepo(identified based on matchinguserTags), then continue with normalCache. For this to work correctly,userTagsmust be unique for each function call. This should be used with caution as it is still experimental. - change to how hashes are calculated. This will cause existing caches to not work correctly. To allow a user to keep old behaviour (during a transition period), the "old" algorithm can be used, with
options("reproducible.useNewDigestAlgorithm" = FALSE). There is a message of this change on package load. - add experimental
cloud*functions, especiallycloudCachewhich allows sharing of Cache among collaborators. Currently only works withgoogledrive - updated
assessDataTypeto consolidateassessDataTypeGDALandassessDataTypeinto single function (#71, @ianmseddy) cc: new function -- a shortcut for some commonly used options forclearCache()- added experimental capacity for
prepInputsto handle.rararchives, on systems with correct binaries to deal with them (#86, @tati-micheletti) - remove
fastdigest::fastdigestas it is not return the identical hash across operating systems
Bug fixes
prepInputson GIS objects that don't useraster::rasterto load object were skippingpostProcess. Fixed.- under some circumstances, the
prepInputswould cause virtually all entries inCHECKSUMS.txtto be deleted. 2 cases where this happened were identified and corrected. data.tableclass objects would give an error sometimes due to use ofattr(DT). Internally, attributes are now added withdata.table::setattrto deal with this.- calling
gdalwarpfromprostProcessnow correctly matches extent (#73, @tati-micheletti) - files from url that have unknown extension are now guessed with by
preProcess(#92, @tati-micheletti)
reproducible 0.2.5
Dependency changes
- Added
remotesto Imports and removeddevtools
New features
-
New value possible for
options(reproducible.useCache = 'overwrite'), which allows use ofCachein cases where the function call has an entry in thecacheRepo, will purge it and add the output of the current call instead. -
New option
reproducible.inputPaths(defaultNULL) andreproducible.inputPathsRecursive(defaultFALSE), which will be used inprepInputsas possible directory sources (searched recursively or not) for files being downloaded/extracted/prepared. This allows the using of local copies of files in (an)other location(s) instead of downloading them. If local location does not have the required files, it will proceed to download so there is little cost in setting this option. If files do exist on local system, the function will attempt to use a hardlink before making a copy. -
dlGoogle()now setsoptions(httr_oob_default = TRUE)if using Rstudio Server. -
Files in
CHECKSUMSnow sorted alphabetically. -
Checksumscan now have aCHECKSUMS.txtfile located in a different place than thedestinationPath -
Attempt to select raster resampling method based on raster type if no method supplied (#63, @ianmseddy)
-
projectInputs -
new function
assessDataTypeGDAL, used inpostProcess, to identify smallestdatatypefor large Raster* objects passed to GDAL system call- when masking and reprojecting large
Rasterobjects, enactgdalwarpsystem call ifraster::canProcessInMemory(x,4) = FALSEfor faster and memory-safe processing - better handling of various data types in
Rasterobjects, including factor rasters
- when masking and reprojecting large
Bug fixes
- Work around internally inside
extractFromArchivefor large (>2GB) zip files. In theRhelp manual,unzipfails for zip files >2GB. This uses a system call if the zip file is too large and fails usingbase::unzip. - Work around for
raster::getDataissues. - Speed up of
Cache()when deeply nested, due togrep(sys.calls(), ...)that would take long and hang. - Bugfix for
preProcess(url = NULL)(#65, @tati-micheletti) - Improved memory performance of
clearCache(#67), especially for largeRasterobjects that are stored as binaryRfiles (i.e.,.rda) - Other minor bugfixes
Other changes
- Deal with new
rasterpackage changes in development version ofrasterpackage - Added checks for float point number issues in raster resolutions produced by
raster::projectRaster .robustDigestnow does not includeCache-added attributes- Additional tests for
preProcess()(#68, @tati-micheletti) - Many new unit tests written, which caught several minor bugs
reproducible 0.2.3
- fix and skip downloading test on CRAN
reproducible 0.2.2
Dependency changes
- Add
futureto Suggests.
New features
- new option on non-Windows OSs to use
futureforCachesaving to SQLite database, viaoptions("reproducible.futurePlan"), if thefuturepackage is installed. This isFALSEby default. - If a
do.callfunction is Cached, previously, it would be labelled in the database asdo.call. Now it attempts to extract the actual function being called by thedo.call. Messaging is similarly changed. - new option
reproducible.ask, logical, indicating whetherclearCacheshould ask for deletions when in an interactive session prepInputs,preProcessanddownloadFilenow havedlFun, to pass a custom function for downloading (e.g., "raster::getData")prepInputswill automatically usereadRDSif the file is a.rds.prepInputswill return alistiffun = "base::load", with a message; can still pass anenvirto obtain standard behaviour ofbase::load.clearCache- new argumentask.- new function
assessDataType, used inpostProcess, to identify smallestdatatypefor Raster* objects, if user does not pass an explicitdatatypeinprepInputsorpostProcess(#39, @CeresBarros).
Bug fixes
- fix problems with tests introduced by recent
git2rupdate (@stewid, #36). .prepareRasterBackedFile-- now will postpend an incremented numeric to a cached copy of a file-backed Raster object, if it already exists. This mirrors the behaviour of the.rdafile. Previously, if two Cache events returned the same file name backing a Raster object, even if the content was different, it would allow the same file name. If either cached object was deleted, therefore, it would cause the other one to break as its file-backing would be missing.- options were wrongly pointing to
spades.XXXand should have beenreproducible.XXX. copyFiledid not perform correctly under all cases; now better handling of these cases, often sending tofile.copy(slower, but more reliable)extractFromArchiveneeded a newChecksumfunction call under some circumstances- several other minor bug fixes.
extractFromArchive-- when dealing with nested zips, not all args were passed in recursively (#37, @CeresBarros)prepInputs-- arguments that were same asCachewere not being correctly passed internally toCache, and if wrapped in Cache, it was not passed into prepInputs. Fixed..prepareFileBackedRasterwas failing in some cases (specifically if it was inside ado.call) (#40, @CeresBarros).Cachewas failing under some cases ofCache(do.call, ...). Fixed.Cache-- when arguments to Cache were the same as the arguments inFUN, Cache would "take" them. Now, they are correctly passed to theFUN.preProcess-- writing to checksums may have produced a warning ifCHECKSUMS.txtwas not present. Now it does not.- numerous other minor bugfixes
Other changes
- most tests now use a standardized approach to attaching libraries, creating objects, paths, enabling easier, error resistant test building
reproducible 0.2.1
New features
-
new functions:
convertPathsandconvertRasterPathsto assist with renaming moved files.
-
prepInputs-- new featuresalsoExtractnow has more options (NULL,NA,"similar") and defaults to extracting all files in an archive (NULL).- skips
postProcessaltogether if nostudyAreaorrasterToMatch. Previously, this would invoke Cache even if there was nothing topostProcess.
Bug fixes
copyFilecorrectly handles directory names containing spaces.makeMemoisablefixed to handle additional edge cases.- other minor bug fixes.
reproducible 0.2.0
New features
-
new functions:
prepInputsto aid in data downloading and preparation problems, solved in a reproducible, Cache-aware way.postProcesswhich is a wrapper for sequences of several other new functions (cropInputs,fixErrors,projectInputs,maskInputs,writeOutputs, anddetermineFilename)downloadFilecan handle Google Drive and ftp/http(s) fileszipCacheandmergeCachecompareNAdoes comparisons with NA as a possible value e.g.,compareNA(c(1,NA), c(2, NA))returnsFALSE, TRUE
-
Cache -- new features:
- new arguments
showSimilar,verbosewhich can help with debugging - new argument
useCachewhich allows turning caching on and off at a high level (e.g., options("useCache")) - new argument
cacheIdwhich allows user to hard code a result from a Cache - deprecated arguments:
digestPathContent-->quick,compareRasterFileLength-->length - Cache arguments now propagate inward to nested
Cachefunction calls, unless explicitly set on the inner functions - more precise messages provided upon each use
- many more
userTagsadded automatically to cache entries so much more powerful searching viashowCache(userTags="something")
- new arguments
-
checksumsnow returns a data.table with the same columns whetherwrite = TRUEorwrite = FALSE. -
clearCacheandshowCachenow give messages and require user intervention if request toclearCachewould be large quantities of data deleted -
memoise::memoisenow used on 3rd run through an identicalCachecall, dramatically speeding up in most cases -
new options:
reproducible.cachePath,reproducible.quick,reproducible.useMemoise,reproducible.useCache,reproducible.useragent,reproducible.verbose -
asPathhas a new argument indicating how deep should the path be considered when included in caching (only relevant whenquick = TRUE) -
New vignette on using Cache
-
Cache is
parallel-safe, meaning there aretryCatcharound every attempt at writing to SQLite database so it can be used safely on multi-threaded machines -
bug fixes, unit tests, more
importsfor packages e.g.,stats -
updates for R 3.6.0 compact storage of sequence vectors
-
experimental pipes (
%>%,%C%) and assign%<% -
several performance enhancements
reproducible 0.1.4
-
mergeCache: a new function to merge two different Cache repositories -
memoise::memoiseis now used onloadFromLocalRepo, meaning that the 3rd timeCache()is run on the same arguments (and the 2nd time in a session), the returned Cache will be from a RAM object via memoise. To stop this behaviour and use only disk-based Caching, setoptions(reproducible.useMemoise = FALSE). -
Cache assign --
%<%can be used instead of normal assign, equivalent tolhs <- Cache(rhs). -
new option: reproducible.verbose, set to FALSE by default, but if set to true may help understand caching behaviour, especially for complex highly nested code.
-
all options now described in
?reproducible. -
All Cache arguments other than FUN and ... will now propagate to internal, nested Cache calls, if they are not specified explicitly in each of the inner Cache calls.
-
Cached pipe operator
%C%-- use to begin a pipe sequence, e.g.,Cache() %C% ... -
Cache arg
sideEffectcan now be a path -
Cache arg
digestPathContentdefault changed from FALSE (was for speed) to TRUE (for content accuracy) -
New function,
searchFull, which shows the full search path, known alternatively as "scope", or "binding environments". It is where R will search for a function when requested by a user. -
Uses
memoise::memoisefor several functions (loadFromLocalRepo,pkgDep,package_dependencies,available.packages) for speed -- will impact memory at the expense of speed. -
New
Requirefunction- attempts to create a lighter weight package reproducibility chain. This function is usable in a reproducible workflow: it includes both installing and loading of packages, it can maintain version numbers, and uses smart caching for speed. In tests, it can evaluate whether 20 packages and their dependencies (~130 packages) are installed and loaded quickly (i.e., if all TRUE, ~0.1 seconds). This is much slower than running
requireon those 20 packages, butrequiredoes not check for dependencies and deal with them if missing: it just errors. This speed should be fast enough for many purposes. - can accept uncommented name, if length 1.
- attempts to create a lighter weight package reproducibility chain. This function is usable in a reproducible workflow: it includes both installing and loading of packages, it can maintain version numbers, and uses smart caching for speed. In tests, it can evaluate whether 20 packages and their dependencies (~130 packages) are installed and loaded quickly (i.e., if all TRUE, ~0.1 seconds). This is much slower than running
-
remove
dplyrfrom Imports -
Add
RCurlto Imports -
change name of
digestRasterto.digestRaster
reproducible 0.1.3
- fix R CMD check errors on Solaris that were not previously resolved
reproducible 0.1.2
- fix R CMD check errors on Solaris
- fix bug in
digestRasteraffecting in-memory rasters - move
rgdalto Suggests
reproducible 0.1.1
- cleanup examples and do run them (per CRAN)
- add tests to ensure all exported (non-dot) functions have examples
reproducible 0.1.0
- A new package, which takes all caching utilities out of the
SpaDESpackage.