vignettes/articles/opendap-acquisition.Rmd
opendap-acquisition.RmdUse EsgResultFile$fetch_subset() when you need the
original values around a location for your own interpolation or
analysis. On rectilinear latitude and longitude grids, it reads the
enclosing 2x2 neighborhood for the requested variable and native time
window through OPeNDAP. The four corners remain separate; the
acquisition does not interpolate them or download the complete NetCDF
file.
The examples below contact external ESGF services when you run them. They are shown without execution here, so no live results or connection speeds are implied. Start with one machine and keep its acquisition directory for resume.
Each request identifies a location, variable and time window.
request_id identifies the demand; the optional
case_id records which analysis uses it. Use distinct
request IDs when several cases share the same physical data.
library(epwshiftr)
requests <- data.frame(
request_id = "singapore-tas-june-2041",
case_id = "example-case",
site_id = "Singapore",
lon = 103.98,
lat = 1.37,
variable_id = "tas",
time_start = "2041-06-01",
time_stop = "2041-06-30T23:59:59"
)
dest <- "climate-neighborhoods"Endpoints are inclusive. A date without a time denotes midnight;
include a time to request the whole final day. Dates must be meaningful
in the source calendar. Native CF coordinates are authoritative,
including for 360_day and noleap data; do not
infer their calendar dates from a POSIX time proxy.
Build an explicit query for the model, experiment, member, variable
and frequency you need. Collect every matching File page with
all = TRUE before narrowing the result to the requested
interval. This searches metadata; it does not read the climate
variable.
query <- esg_query("https://esgf-data.dkrz.de")$activity_id(
"ScenarioMIP"
)$source_id("MPI-ESM1-2-LR")$experiment_id("ssp126")$variant_label(
"r1i1p1f1"
)$variable_id("tas")$frequency("mon")$params(table_id = "Amon")
files <- query$collect(type = "File", all = TRUE, limit = FALSE)
files <- files$filter_time(
requests$time_start,
requests$time_stop,
method = "drs"
)
candidates <- files$access_plan()
attr(candidates, "directory_complete")access_plan() lists compatible OPeNDAP Replica
candidates. Successful data reads cannot establish that missing query
pages were collected. The separate directory_complete flag
records that distinction; filtering or deliberately slicing an already
complete directory retains its directory evidence.
result <- files$fetch_subset(
requests,
dest,
workers = 4L,
node_workers = 2L,
timeout = 180,
retries = 2L,
network_id = "single-machine"
)
result$directory_complete
result$complete
subset_status(dest, "nodes")The package switches to another compatible Replica after a read
failure and updates node ranking from actual demand reads. It does not
require a separate speed test of every candidate. A file whose
candidates fail releases its worker so other files can continue;
retries bounds later attempts. Node observations belong to
the current client and network_id, so another machine can
have a different ranking.
result$complete concerns native coverage of the selected
Files. result$directory_complete concerns File-query
pagination. Neither establishes that every variable, frequency, model or
year required by your study is present. Check those study requirements
separately. A case label is an association, not a scientific acceptance
rule.
max_values limits native weather values in each request.
Its default remains 8192, including all four corners. For a service that
benefits from fewer, larger requests, try 65536 in a separate
acquisition directory before changing an existing run. Only consecutive
required native time indices are combined; gaps, physical File
boundaries and the four unaggregated corners remain intact. A different
budget can resume previously saved blocks without reading them
again.
result <- files$fetch_subset(
requests,
"climate-neighborhoods-timing",
workers = 4L,
node_workers = 4L,
max_values = 65536L,
replica_cooldown = 60,
network_id = "single-machine"
)node_workers already controls simultaneous File readers
on each data node. Compare useful native values per second and failures
before increasing it; a larger worker count does not create more node
slots. When several machines use one service, consider their combined
allowance.
Replica cooling is optional and defaults to zero, retaining immediate
finite retries. With replica_cooldown = 60, recent
transport failures defer that exact File URL for 60 seconds on the
current client/network identity. Repeated failures increase that
interval up to eightfold; known File absences, including explicit HTTP
404 or 410, use the eightfold interval immediately and remain
File-local. Generic NetCDF: DAP failure errors alone do not
establish a node fault. Node cooling requires at least three distinct
Files with network/service, generic DAP or native I/O failures. Each
node retains evidence across the greater of five minutes, eight cooldown
intervals and three times its longest recorded failed-job duration,
capped at the existing one-day history horizon. Invalid or missing
durations do not extend this window. A slow failure on one node does not
extend another node’s evidence. Its recovery spacing also increases up
to eightfold with further failures. A successful native data read resets
that node’s failure streak; a successful read of the same File URL also
resets its endpoint backoff. Content and CF identity checks continue to
apply to every Replica.
After a corroborated node cooldown, the first recovery uses one reader until actual native values succeed. Metadata-only success does not reopen every node slot. The configured node allowance returns after a native success.
Cooling never occupies a sleeping worker. Other Files and compatible candidates continue; Replica discovery remains available when known URLs are cooling. If all compatible candidates are cooling, the source stays incomplete with a saved gap. A later call retries after the deadline and reuses verified blocks. The existing attempt ledger supplies these deadlines across calls; no extra speed checks or separate health database are required.
Native selection evidence is saved before the first weather block, so a later read failure can retain the exact native denominator and four-corner membership. After the acquisition writer closes, inspect checked physical coverage:
coverage <- subset_status(dest, "coverage")
timing <- subset_status(dest, "timing", source_key = unique(coverage$source_key))complete requires every requested native time at all
four original corners. The coverage view preserves request and case
associations; deduplicate physical File/location/window keys for totals.
Unknown axes retain NA expected counts, and an empty native
selection stays incomplete. status, gap_kind,
retryable and retry_after distinguish partial
data, nonterminal work, transport failures, cooling and nonretryable
identity/selection problems. Job labels alone do not certify raw
coverage. source_key can restrict these two views before
reading or hashing unrelated artifacts. These views read local data only
and require the unique acquisition writer to be closed.
Timing reports recorded open/metadata phases and successful
native-read phases separately from whole failed tasks. A failed task may
already have committed useful blocks, so its full duration is not pure
waste or an additional disjoint phase. Historical phases without
evidence remain NA. Acquisition coverage also does not
certify scientific quality of native missing values.
A caller can use the structured gaps for a finite recovery campaign after its first pass: retain the original identities, retry only eligible incomplete windows, respect cooldown deadlines, and stop on a fixed budget, no progress or a nonretryable blocker. Expiration alone does not launch a later acquisition. Persist the spent budget across restarts and report unresolved gaps explicitly.
After an acquisition call returns, inspect its local results:
subset_status(dest)
subset_status(dest, "attempts")
raw <- read_subset(dest, case_id = "example-case")
head(raw$values)
head(raw$neighborhoods)
raw$gaps$directory
raw$gaps$unmatched
raw$gaps$incomplete_requests
raw$gaps$invalid_blocksraw$values contains unique native point/time values with
their coordinates and CF time information.
raw$neighborhoods relates them to each location’s corners
and requested window; raw$links retains the case/request
associations. Keep these together when comparing interpolation
algorithms.
subset_status() and read_subset() use local
data only. Directory gaps, unmatched requests, missing native coverage
and invalid saved blocks remain explicit; the reader does not fill them
through hidden network access.
Repeat the acquisition with the same requests and destination:
resumed <- files$fetch_subset(
requests,
dest,
resume = TRUE,
workers = 4L,
network_id = "single-machine"
)
raw <- read_subset(dest, case_id = "example-case")
raw$gaps$incomplete_requestsVerified saved blocks are reused and only outstanding demand is read.
A fully saved request does not need another climate-data read. With the
default discover = TRUE, an original, unsliced partial File
query automatically collects its missing pages and saves the completed
directory for local reuse on repeat calls. An explicitly sliced result
is never expanded automatically, even when it contains every held row.
Existing directory gaps remain visible when collection context is
unknown or discovery is disabled. To resolve a partial original
directory, explicitly collect the original File query with
all = TRUE and supply that complete result to
fetch_subset().
Keep one writer per acquisition directory. If work is later divided between machines, give each machine a fixed File list and its own destination, and retain the request/case associations when combining results.
See Work with ESGF Query Results for query selection, and Troubleshoot ESGF Workflows for access failures.