| Title: | 'Circuitscape' and 'Omniscape' Connectivity Analysis via 'Julia' |
|---|---|
| Description: | Provides an R-native interface to the 'Circuitscape.jl' and 'Omniscape.jl' 'Julia' packages for landscape connectivity modeling using circuit theory. Users work entirely in R with familiar objects (SpatRaster, file paths) while 'Julia' handles computation invisibly. Supports all four 'Circuitscape' modes (pairwise, one-to-all, all-to-one, advanced) and 'Omniscape' moving-window analysis. Methods are described in McRae (2006) <doi:10.1111/j.0014-3820.2006.tb00500.x> and Landau et al. (2021) <doi:10.21105/joss.02829>. |
| Authors: | Matthew Kling [aut, cre, cph] |
| Maintainer: | Matthew Kling <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.1.9000 |
| Built: | 2026-10-20 05:09:17 UTC |
| Source: | https://github.com/matthewkling/circuitscaper |
Solve a single circuit with user-specified source and ground layers.
cs_advanced( resistance, source, ground, resistance_is = "resistances", ground_is = "resistances", use_unit_currents = FALSE, use_direct_grounds = FALSE, short_circuit = NULL, source_ground_conflict = "keepall", four_neighbors = FALSE, avg_resistances = FALSE, solver = "cg+amg", output_dir = NULL, verbose = FALSE )cs_advanced( resistance, source, ground, resistance_is = "resistances", ground_is = "resistances", use_unit_currents = FALSE, use_direct_grounds = FALSE, short_circuit = NULL, source_ground_conflict = "keepall", four_neighbors = FALSE, avg_resistances = FALSE, solver = "cg+amg", output_dir = NULL, verbose = FALSE )
resistance |
A terra::SpatRaster or file path. The resistance (or conductance) surface. Higher values represent greater resistance to movement. |
source |
A terra::SpatRaster or file path. Source current strengths (amps per cell). Cells with value 0 or NA are not sources. |
ground |
A terra::SpatRaster or file path. Ground node values.
Interpretation depends on |
resistance_is |
Character. Whether the resistance surface represents
|
ground_is |
Character. Whether the ground raster values represent
|
use_unit_currents |
Logical. If |
use_direct_grounds |
Logical. If |
short_circuit |
Optional terra::SpatRaster or file path. Raster
identifying short-circuit regions (aka polygons). Cells sharing the same
positive integer value are treated as short-circuit regions with zero
resistance between them. Default |
source_ground_conflict |
Character. How to resolve cells that appear in
both the source and ground rasters: |
four_neighbors |
Logical. Use 4-neighbor (rook) connectivity instead of
8-neighbor (queen). Default |
avg_resistances |
Logical. When using 8-neighbor connectivity, compute
the resistance of diagonal connections as the average of the two cells
rather than their sum. Default |
solver |
Character. Solver to use: |
output_dir |
Optional character path. If provided, output files persist
there. Default |
verbose |
Logical. Print Circuitscape solver output. Default |
Unlike the other Circuitscape modes, advanced mode does not iterate over focal nodes. Instead, the user provides explicit source current and ground conductance rasters, and a single circuit is solved. This gives full control over the current injection pattern and is useful for modeling specific scenarios such as directional movement between a defined source area and destination.
A terra::SpatRaster with the following layers:
Current density at each cell.
Voltage at each cell. Voltage is analogous to movement probability and decreases with distance from sources.
McRae, B.H. (2006). Isolation by resistance. Evolution, 60(8), 1551–1561. doi:10.1111/j.0014-3820.2006.tb00500.x
Circuitscape.jl: https://docs.circuitscape.org/Circuitscape.jl/latest/
cs_pairwise(), cs_one_to_all(), cs_all_to_one(), cs_setup()
library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) origin <- rast(system.file("extdata/source.tif", package = "circuitscaper")) dest <- rast(system.file("extdata/ground.tif", package = "circuitscaper")) result <- cs_advanced(res, origin, dest, ground_is = "conductances") plot(result)library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) origin <- rast(system.file("extdata/source.tif", package = "circuitscaper")) dest <- rast(system.file("extdata/ground.tif", package = "circuitscaper")) result <- cs_advanced(res, origin, dest, ground_is = "conductances") plot(result)
For each focal node in turn, inject current at all other focal nodes and ground that single node.
cs_all_to_one( resistance, locations, resistance_is = "resistances", four_neighbors = FALSE, avg_resistances = FALSE, short_circuit = NULL, included_pairs = NULL, write_voltage = FALSE, cumulative_only = TRUE, source_strengths = NULL, solver = "cg+amg", output_dir = NULL, verbose = FALSE )cs_all_to_one( resistance, locations, resistance_is = "resistances", four_neighbors = FALSE, avg_resistances = FALSE, short_circuit = NULL, included_pairs = NULL, write_voltage = FALSE, cumulative_only = TRUE, source_strengths = NULL, solver = "cg+amg", output_dir = NULL, verbose = FALSE )
resistance |
A terra::SpatRaster or file path. The resistance (or
conductance) surface. Higher values represent greater resistance to
movement. Use the |
locations |
Focal node locations, provided as any of:
|
resistance_is |
Character. Whether the resistance surface represents
|
four_neighbors |
Logical. Use 4-neighbor (rook) connectivity instead of
8-neighbor (queen). Default |
avg_resistances |
Logical. When using 8-neighbor connectivity, compute
the resistance of diagonal connections as the average of the two cells
rather than their sum. Default |
short_circuit |
Optional terra::SpatRaster or file path. Raster
identifying short-circuit regions (aka polygons). Cells sharing the same
positive integer value are treated as short-circuit regions with zero
resistance between them. Default |
included_pairs |
Optional character file path. A text file specifying
which pairs of focal nodes to include or exclude from analysis. See the
Circuitscape documentation for the file format. Default |
write_voltage |
Logical. Write voltage maps. Default |
cumulative_only |
Logical. If |
source_strengths |
Optional. Variable current injection strengths for each focal node. Can be:
|
solver |
Character. Solver to use: |
output_dir |
Optional character path. If provided, output files persist
there. Default |
verbose |
Logical. Print Circuitscape solver output. Default |
All-to-one mode iterates over each focal node. In each iteration, all other focal nodes are injected with 1 amp of current each, and the focal node is connected to ground. This produces a current map showing how current converges on that node from across the landscape.
This mode is useful for identifying the most accessible or reachable sites in the network, emphasizing current flow toward each ground node. The cumulative map sums across all iterations and highlights cells that are important for connectivity across the full set of nodes.
A terra::SpatRaster with the following layers:
Current flow summed across all iterations.
Per-node current map for focal node N, where
N is the integer node ID from the locations raster. One layer
per focal node.
McRae, B.H. (2006). Isolation by resistance. Evolution, 60(8), 1551–1561. doi:10.1111/j.0014-3820.2006.tb00500.x
Circuitscape.jl: https://docs.circuitscape.org/Circuitscape.jl/latest/
cs_pairwise(), cs_one_to_all(), cs_advanced(), cs_setup()
library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) coords <- matrix(c(10, 40, 40, 40, 10, 10, 40, 10), ncol = 2, byrow = TRUE) result <- cs_all_to_one(res, coords) plot(result)library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) coords <- matrix(c(10, 40, 40, 40, 10, 10, 40, 10), ncol = 2, byrow = TRUE) result <- cs_all_to_one(res, coords) plot(result)
Downloads and installs Julia, Circuitscape.jl, and Omniscape.jl. This is the recommended first step after installing the circuitscaper R package.
cs_install_julia(force = FALSE, version = "latest")cs_install_julia(force = FALSE, version = "latest")
force |
Logical. If |
version |
Character. Julia version to install. Default |
In interactive sessions, prompts for confirmation before downloading. In non-interactive sessions (e.g., CI), proceeds without prompting.
Invisibly returns TRUE on success, FALSE if cancelled.
## Not run: cs_install_julia() ## End(Not run)## Not run: cs_install_julia() ## End(Not run)
Tests whether Julia is installed and the Circuitscape and Omniscape Julia packages can be loaded. This is a lightweight check that does not initialize a full Julia session. It is used internally by example code and can be called by users to verify their setup before running analyses.
cs_julia_available()cs_julia_available()
TRUE if Julia is found (in the places cs_setup() searches) and
the 'Circuitscape' and 'Omniscape' Julia packages load successfully,
FALSE otherwise.
cs_julia_available()cs_julia_available()
For each focal node in turn, inject current at that node and ground all other focal nodes simultaneously.
cs_one_to_all( resistance, locations, resistance_is = "resistances", four_neighbors = FALSE, avg_resistances = FALSE, short_circuit = NULL, included_pairs = NULL, write_voltage = FALSE, cumulative_only = TRUE, source_strengths = NULL, solver = "cg+amg", output_dir = NULL, verbose = FALSE )cs_one_to_all( resistance, locations, resistance_is = "resistances", four_neighbors = FALSE, avg_resistances = FALSE, short_circuit = NULL, included_pairs = NULL, write_voltage = FALSE, cumulative_only = TRUE, source_strengths = NULL, solver = "cg+amg", output_dir = NULL, verbose = FALSE )
resistance |
A terra::SpatRaster or file path. The resistance (or
conductance) surface. Higher values represent greater resistance to
movement. Use the |
locations |
Focal node locations, provided as any of:
|
resistance_is |
Character. Whether the resistance surface represents
|
four_neighbors |
Logical. Use 4-neighbor (rook) connectivity instead of
8-neighbor (queen). Default |
avg_resistances |
Logical. When using 8-neighbor connectivity, compute
the resistance of diagonal connections as the average of the two cells
rather than their sum. Default |
short_circuit |
Optional terra::SpatRaster or file path. Raster
identifying short-circuit regions (aka polygons). Cells sharing the same
positive integer value are treated as short-circuit regions with zero
resistance between them. Default |
included_pairs |
Optional character file path. A text file specifying
which pairs of focal nodes to include or exclude from analysis. See the
Circuitscape documentation for the file format. Default |
write_voltage |
Logical. Write voltage maps. Default |
cumulative_only |
Logical. If |
source_strengths |
Optional. Variable current injection strengths for each focal node. Can be:
|
solver |
Character. Solver to use: |
output_dir |
Optional character path. If provided, output files persist
there. Default |
verbose |
Logical. Print Circuitscape solver output. Default |
One-to-all mode iterates over each focal node. In each iteration, the focal node is injected with 1 amp of current and all remaining focal nodes are simultaneously connected to ground. This produces a current map showing how current spreads from that node through the landscape to reach the others.
This mode is useful for mapping how well each site is connected to the rest of the focal node network, emphasizing current dispersal from each source. The cumulative map sums across all iterations and highlights cells that are important for connectivity across the full set of nodes.
A terra::SpatRaster with the following layers:
Current flow summed across all iterations.
Per-node current map for focal node N, where
N is the integer node ID from the locations raster. One layer
per focal node.
McRae, B.H. (2006). Isolation by resistance. Evolution, 60(8), 1551–1561. doi:10.1111/j.0014-3820.2006.tb00500.x
Circuitscape.jl: https://docs.circuitscape.org/Circuitscape.jl/latest/
cs_pairwise(), cs_all_to_one(), cs_advanced(), cs_setup()
library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) coords <- matrix(c(10, 40, 40, 40, 10, 10, 40, 10), ncol = 2, byrow = TRUE) result <- cs_one_to_all(res, coords) plot(result)library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) coords <- matrix(c(10, 40, 40, 40, 10, 10, 40, 10), ncol = 2, byrow = TRUE) result <- cs_one_to_all(res, coords) plot(result)
Compute pairwise effective resistances and cumulative current flow between all pairs of focal nodes.
cs_pairwise( resistance, locations, resistance_is = "resistances", four_neighbors = FALSE, avg_resistances = FALSE, short_circuit = NULL, included_pairs = NULL, write_voltage = FALSE, cumulative_only = TRUE, source_strengths = NULL, solver = "cg+amg", output_dir = NULL, verbose = FALSE )cs_pairwise( resistance, locations, resistance_is = "resistances", four_neighbors = FALSE, avg_resistances = FALSE, short_circuit = NULL, included_pairs = NULL, write_voltage = FALSE, cumulative_only = TRUE, source_strengths = NULL, solver = "cg+amg", output_dir = NULL, verbose = FALSE )
resistance |
A terra::SpatRaster or file path. The resistance (or
conductance) surface. Higher values represent greater resistance to
movement. Use the |
locations |
Focal node locations, provided as any of:
|
resistance_is |
Character. Whether the resistance surface represents
|
four_neighbors |
Logical. Use 4-neighbor (rook) connectivity instead of
8-neighbor (queen). Default |
avg_resistances |
Logical. When using 8-neighbor connectivity, compute
the resistance of diagonal connections as the average of the two cells
rather than their sum. Default |
short_circuit |
Optional terra::SpatRaster or file path. Raster
identifying short-circuit regions (aka polygons). Cells sharing the same
positive integer value are treated as short-circuit regions with zero
resistance between them. Default |
included_pairs |
Optional character file path. A text file specifying
which pairs of focal nodes to include or exclude from analysis. See the
Circuitscape documentation for the file format. Default |
write_voltage |
Logical. Write voltage maps. Default |
cumulative_only |
Logical. If |
source_strengths |
Optional. Variable current injection strengths for each focal node. Can be:
|
solver |
Character. Solver to use: |
output_dir |
Optional character path. If provided, output files persist
there. Default |
verbose |
Logical. Print Circuitscape solver output. Default |
Pairwise mode iterates over every unique pair of focal nodes. For each pair, one node is injected with 1 amp of current and the other is connected to ground. The effective resistance between the pair is recorded, and the resulting current flow is accumulated across all pairs into a cumulative current map that highlights important movement corridors.
This is the most common Circuitscape mode and is typically used to quantify connectivity between discrete habitat patches or populations. The resistance matrix can be used as a distance metric in analyses such as isolation by resistance.
A named list with:
A terra::SpatRaster. By default contains a single
cumulative_current layer (current flow summed across all pairs). When
cumulative_only = FALSE, additional per-pair layers are included
(e.g., current_1_2, current_1_3). When write_voltage = TRUE,
per-pair voltage layers are included (e.g., voltage_1_2,
voltage_1_3).
A symmetric numeric matrix of pairwise effective resistances between focal nodes, with node IDs as row and column names.
McRae, B.H. (2006). Isolation by resistance. Evolution, 60(8), 1551–1561. doi:10.1111/j.0014-3820.2006.tb00500.x
Circuitscape.jl: https://docs.circuitscape.org/Circuitscape.jl/latest/
cs_one_to_all(), cs_all_to_one(), cs_advanced(), cs_setup()
library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) coords <- matrix(c(10, 40, 40, 40, 10, 10, 40, 10), ncol = 2, byrow = TRUE) result <- cs_pairwise(res, coords, cumulative_only = FALSE) plot(result$current_map) result$resistance_matrixlibrary(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) coords <- matrix(c(10, 40, 40, 40, 10, 10, 40, 10), ncol = 2, byrow = TRUE) result <- cs_pairwise(res, coords, cumulative_only = FALSE) plot(result$current_map) result$resistance_matrix
Initialize the Julia session and load the Circuitscape and Omniscape Julia
packages. This is called automatically on first use of any cs_* or os_*
function. Call explicitly to control the Julia path, number of threads, or
pre-warm the session.
cs_setup(julia_home = NULL, threads = 1L, quiet = TRUE, ...)cs_setup(julia_home = NULL, threads = 1L, quiet = TRUE, ...)
julia_home |
Character. Path to the Julia |
threads |
Integer. Number of Julia threads to start. Default |
quiet |
Logical. Suppress Julia startup messages. Default |
... |
Additional arguments passed to |
cs_setup() does not install Julia or Julia packages. If Julia is not
found or the required packages are missing, it throws an informative error
directing you to cs_install_julia().
cs_setup() will:
Verify that Julia is installed and accessible.
Verify that the Circuitscape and Omniscape Julia packages are installed.
Load both packages and warm up the JIT compiler.
Once Julia is initialized, it stays warm for the R session. Subsequent calls
to cs_setup() return immediately.
Julia's thread count is fixed when Julia starts and cannot be changed
mid-session. Multi-threading is used by os_run() when
parallelize = TRUE. Circuitscape functions (cs_pairwise,
cs_one_to_all, etc.) do not benefit from multiple threads.
cs_setup(threads = 4) os_run(resistance, radius = 50, parallelize = TRUE)
Call cs_setup(threads = ) before anything else starts Julia, including
JuliaCall::julia_setup() or another package that uses JuliaCall. If you
need to start Julia yourself, set the thread count first with
Sys.setenv(JULIA_NUM_THREADS = "4,0"). The ,0 (no interactive
threads) matters: Omniscape releases before 0.6.3 fail in parallel when
Julia has an interactive thread, and os_run() then falls back to a
serial run with a warning.
Invisibly returns TRUE on success.
McRae, B.H. (2006). Isolation by resistance. Evolution, 60(8), 1551–1561. doi:10.1111/j.0014-3820.2006.tb00500.x
Landau, V.A., Shah, V.B., Anantharaman, R. & Hall, K.R. (2021). Omniscape.jl: Software to compute omnidirectional landscape connectivity. Journal of Open Source Software, 6(57), 2829. doi:10.21105/joss.02829
Circuitscape.jl: https://docs.circuitscape.org/Circuitscape.jl/latest/
Omniscape.jl: https://docs.circuitscape.org/Omniscape.jl/latest/
cs_install_julia(), cs_pairwise(), os_run()
cs_setup() cs_setup(threads = 4) cs_setup(julia_home = "/usr/local/julia/bin")cs_setup() cs_setup(threads = 4) cs_setup(julia_home = "/usr/local/julia/bin")
Creates a condition specification for use with the condition argument of
os_run(). Conditional connectivity restricts which source cells are
connected to each target, based on how their values on a condition layer
(e.g., climate, land cover class) compare. Conditions can compare
present-day values at both sources and targets, or present-day values at
sources against future values at targets (e.g., for climate-tracking
connectivity).
os_condition( present, future = NULL, type = c("equal", "within"), lower = NULL, upper = NULL )os_condition( present, future = NULL, type = c("equal", "within"), lower = NULL, upper = NULL )
present |
A single-layer terra::SpatRaster or file path giving present-day condition values. Must align with the resistance surface. |
future |
Optional single-layer terra::SpatRaster or file path giving
future condition values. If supplied, each source's present value is
compared against the target's future value. If |
type |
Character. How source and target values are compared:
|
lower, upper
|
Numeric. Required when |
Omniscape evaluates each moving-window target against every source cell in
the window, and sets the strength of any source that fails the comparison
to zero for that target. The target's value is summarized over its block
(see block_size in os_run()): the median for "within", and the mode
for "equal". When block_size = 1 this is simply the target cell's value.
Omniscape requires a condition value at every source cell. Source cells
with a missing (NA) present-day condition value are not filtered out;
they remain sources for every target. os_run() warns if it detects this.
"equal" compares values exactly, so it is only meaningful for
categorical (integer-valued) layers; a warning is issued if a
SpatRaster supplied with type = "equal" contains non-integer values.
Up to two conditions can be combined by passing a list of two
os_condition() objects to os_run(); a source must satisfy both to be
connected.
An object of class "os_condition": a list with elements
present, future, type, lower, and upper.
Omniscape.jl conditional connectivity options: https://docs.circuitscape.org/Omniscape.jl/latest/usage/
library(terra) temp_now <- rast(nrows = 20, ncols = 20, vals = rep(1:20, each = 20)) temp_future <- temp_now + 2 # Climate-tracking: connect sources to targets whose future temperature is # between 1 unit cooler and 3 units warmer than the source's present value # (i.e., source - target_future within [-3, 1]) os_condition(temp_now, future = temp_future, lower = -3, upper = 1) # Categorical: connect only cells of the same land cover class landcover <- rast(nrows = 20, ncols = 20, vals = sample(1:3, 400, TRUE)) os_condition(landcover, type = "equal")library(terra) temp_now <- rast(nrows = 20, ncols = 20, vals = rep(1:20, each = 20)) temp_future <- temp_now + 2 # Climate-tracking: connect sources to targets whose future temperature is # between 1 unit cooler and 3 units warmer than the source's present value # (i.e., source - target_future within [-3, 1]) os_condition(temp_now, future = temp_future, lower = -3, upper = 1) # Categorical: connect only cells of the same land cover class landcover <- rast(nrows = 20, ncols = 20, vals = sample(1:3, 400, TRUE)) os_condition(landcover, type = "equal")
Performs an Omniscape analysis, computing omnidirectional landscape connectivity using a moving window approach based on circuit theory.
os_run( resistance, radius, source_strength = NULL, block_size = 1L, source_threshold = 0, r_cutoff = Inf, resistance_is = "resistances", calc_normalized_current = TRUE, calc_flow_potential = TRUE, condition = NULL, condition_type = NULL, parallelize = FALSE, julia_threads = 2L, solver = "cg+amg", output_dir = NULL, verbose = FALSE )os_run( resistance, radius, source_strength = NULL, block_size = 1L, source_threshold = 0, r_cutoff = Inf, resistance_is = "resistances", calc_normalized_current = TRUE, calc_flow_potential = TRUE, condition = NULL, condition_type = NULL, parallelize = FALSE, julia_threads = 2L, solver = "cg+amg", output_dir = NULL, verbose = FALSE )
resistance |
A terra::SpatRaster or file path. The resistance (or conductance) surface. Higher values represent greater resistance to movement. |
radius |
Numeric. Moving window radius in pixels. This determines the maximum distance over which connectivity is evaluated from each source pixel. |
source_strength |
Optional terra::SpatRaster or file path. Source
strength weights, often derived from habitat quality or suitability, where
higher values indicate stronger sources of movement. If |
block_size |
Integer. Aggregation block size for source points. Default
|
source_threshold |
Numeric. Minimum source strength to include a pixel.
Default |
r_cutoff |
Numeric. Maximum resistance value for a cell to be included
as a source when |
resistance_is |
Character. Whether the resistance surface represents
|
calc_normalized_current |
Logical. Compute normalized current flow.
Default |
calc_flow_potential |
Logical. Compute flow potential. Default |
condition |
Optional conditional connectivity specification, which
restricts each target to sources with compatible values on one or two
condition layers. Either an |
condition_type |
Deprecated. Use
|
parallelize |
Logical. Use Julia multithreading. Default |
julia_threads |
Integer. Number of Julia threads to start if
|
solver |
Character. Solver to use: |
output_dir |
Optional character path. If provided, output files persist
there. Default |
verbose |
Logical. Print Omniscape output. Default |
A terra::SpatRaster with the following layers (depending on options):
Raw cumulative current flow. Always present. Higher values indicate cells that carry more current across all moving-window iterations.
Expected current under homogeneous resistance
(if calc_flow_potential = TRUE). Reflects the spatial configuration
of sources independently of landscape resistance.
Cumulative current divided by flow potential
(if calc_normalized_current = TRUE). Values greater than 1 indicate
cells where connectivity is higher than expected given the source
geometry; values less than 1 indicate relative barriers. This is
typically the most informative layer for identifying corridors and
pinch points.
Landau, V.A., Shah, V.B., Anantharaman, R. & Hall, K.R. (2021). Omniscape.jl: Software to compute omnidirectional landscape connectivity. Journal of Open Source Software, 6(57), 2829. doi:10.21105/joss.02829
Omniscape.jl: https://docs.circuitscape.org/Omniscape.jl/latest/
os_condition(), cs_pairwise(), cs_setup()
library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) result <- os_run(res, radius = 10) plot(result) # Conditional connectivity: only connect cells in the same zone # (here, the left and right halves of the landscape) zones <- (init(res, "col") > ncol(res) / 2) + 1 result_cond <- os_run(res, radius = 10, condition = zones) plot(result_cond)library(terra) res <- rast(system.file("extdata/resistance.tif", package = "circuitscaper")) result <- os_run(res, radius = 10) plot(result) # Conditional connectivity: only connect cells in the same zone # (here, the left and right halves of the landscape) zones <- (init(res, "col") > ncol(res) / 2) + 1 result_cond <- os_run(res, radius = 10, condition = zones) plot(result_cond)