Circuitscape / Omniscape.jl

Functions to compute omnidirectional landscape connectivity using circuit theory and the Omniscape algorithm.
https://docs.circuitscape.org/Omniscape.jl/stable/
MIT License
58 stars 12 forks source link

ERROR: LoadError: BoundsError: attempt to access 1×1 Matrix{Union{Missing, Number}} at index [1:201, 1:201] #109

Closed amywaananen closed 3 years ago

amywaananen commented 3 years ago

Good morning!

I am getting the following error when I attempt to run Omniscape with conditional connectivity options. Do you have any suggestions about what might be going on?

Thank you, Amy

ERROR: LoadError: BoundsError: attempt to access 1×1 Matrix{Union{Missing, Number}} at index [1:201, 1:201]
Stacktrace:
 [1] throw_boundserror(A::Matrix{Union{Missing, Number}}, I::Tuple{UnitRange{Int64}, UnitRange{Int64}})
   @ Base .\abstractarray.jl:651
 [2] checkbounds
   @ .\abstractarray.jl:616 [inlined]
 [3] _getindex
   @ .\multidimensional.jl:831 [inlined]
 [4] getindex
   @ .\abstractarray.jl:1170 [inlined]
 [5] source_target_match!(source_subset::Matrix{Union{Missing, Float64}}, n_conditions::Int64, condition_layers::Omniscape.ConditionLayers, conditions::Omniscape.Conditions, ylower::Int64, yupper::Int64, xlower::Int64, xupper::Int64, ylower_buffered::Int64, yupper_buffered::Int64, xlower_buffered::Int64, xupper_buffered::Int64)
   @ Omniscape C:\Users\waana001\.julia\packages\Omniscape\lcfqp\src\utils.jl:214
 [6] get_source(source_array::Matrix{Union{Missing, Float64}}, arguments::Dict{String, Int64}, os_flags::Omniscape.OmniscapeFlags, condition_layers::Omniscape.ConditionLayers, conditions::Omniscape.Conditions, target::Omniscape.Target)
   @ Omniscape C:\Users\waana001\.julia\packages\Omniscape\lcfqp\src\utils.jl:172
 [7] calc_correction(arguments::Dict{String, Int64}, os_flags::Omniscape.OmniscapeFlags, cs_cfg::Dict{String, String}, cs_flags::Circuitscape.RasterFlags, condition_layers::Omniscape.ConditionLayers, conditions::Omniscape.Conditions, precision::DataType)
   @ Omniscape C:\Users\waana001\.julia\packages\Omniscape\lcfqp\src\utils.jl:560
 [8] run_omniscape(cfg::Dict{String, String}, resistance::Matrix{Union{Missing, Float64}}; reclass_table::Matrix{Union{Missing, Float64}}, 
source_strength::Matrix{Union{Missing, Float64}}, condition1::Matrix{Union{Missing, Float64}}, condition2::Matrix{Union{Missing, Float64}}, condition1_future::Matrix{Union{Missing, Float64}}, condition2_future::Matrix{Union{Missing, Float64}}, wkt::String, geotransform::Vector{Float64}, write_outputs::Bool)
   @ Omniscape C:\Users\waana001\.julia\packages\Omniscape\lcfqp\src\main.jl:240
 [9] top-level scope
   @ Untitled-1:26
in expression starting at Untitled-1:26
vlandau commented 3 years ago

Hi @amywaananen, thanks for posting this issue! Could you post the code that caused the issue here? I suspect that there is an issue with the raster for your first condition. It looks like it is a 1 by 1 array when it should be the same size as your resistance surface.

amywaananen commented 3 years ago

Yes, code below. Let me know if I should send you the files. Thanks!

using Pkg; Pkg.add(["Omniscape","GeoData", "Plots"])
using Omniscape, GeoData, Plots

# Read in the resistance layers and assign info to variables for omniscape settings
resistance, wkt, transform = Omniscape.read_raster("01_Data\\wca_conductance.tif", Float64)

# Specify the configuration settings for the omniscape run

config = Dict{String, String}(
    "radius" => "100", # radius of the moving window in *pixels*
    "block_size" => "21", 
    "project_name" => "md_nlcd_omniscape_output", # name of the folder to create for output
    "source_from_resistance" => "true", # Source matrix comes from the resistance matrix
    "r_cutoff" => "20", # Only grassland pixels should be sources
    "resistance_is_conductance" => "false",
    "reclassify_resistance" => "false", # use the reclass_table for the resistnace matrix
    "calc_normalized_current" => "true", # calculate the normalized current
    "calc_flow_potential" => "true",  # calculate the "flow potential" - the  flow if resistance was 1 at all pixels
    "conditional" => "true",
    "comparison1" => "within",
    "compare_to_future" => "1",
    "condition1_future_file" => "01_Data\\wca_conductance_future.tif"
)

currmap, flow_pot, norm_current = run_omniscape(config,
                                                resistance,
                                                wkt = wkt,
                                                geotransform = transform,
                                                write_outputs = true)
vlandau commented 3 years ago

Ah, so the issue here is that for this omniscape method (as opposed to the INI method) all rasters need to be provided as in-memory objects (like what you did with the resistance surface). For this method you can't provide file paths. See here in the docs for all of the things that need to be passed as arguments as opposed to items in the configuration dictionary.

amywaananen commented 3 years ago

Ah, I see! Makes sense. I tried providing the future raster as an in-memory object earlier, but hadn't realized that I needed to include the raster as an argument for both condition1 and condition1_future in run_omniscape(). It's working now. Thanks!

vlandau commented 3 years ago

Excellent!! I'm glad it worked out. Don't hesitate to open new issues as any other roadblocks come up!

ranjanan commented 3 years ago

Is there a nice user-friendly error message that can be thrown if this is a standard error?

vlandau commented 3 years ago

For now I think the docs do a good enough job describing it, but if it comes up again I'll prioritize creating an error