diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61dc0336..feb0cfa1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,6 @@ jobs: fail_ci_if_error: false docs: - needs: test name: Documentation runs-on: ubuntu-latest continue-on-error: true @@ -75,7 +74,7 @@ jobs: - name: Setup julia uses: julia-actions/setup-julia@v2 with: - version: 'lts' + version: '1.12' arch: x64 - name: Build Docs diff --git a/docs/Project.toml b/docs/Project.toml index 30f00a88..c10cbab2 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,6 +1,4 @@ [deps] -Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" -Compose = "a81c6b42-2e10-5240-aca2-a61377ecd94b" DistributedFactorGraphs = "b5cc3c7e-6572-11e9-2517-99fb8daf2f04" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" GraphMakie = "1ecd5474-83a3-4783-bb4f-06765db800d2" diff --git a/docs/src/DataStructure.md b/docs/src/DataStructure.md index f0862dba..65f0c811 100644 --- a/docs/src/DataStructure.md +++ b/docs/src/DataStructure.md @@ -37,16 +37,11 @@ Accessible properties for each of the factor structures: - [`VariableSummary`](@ref) - [`FactorSummary`](@ref) -## DFG Portable and Storeable types +## DFG full types (solvable, portable and storeable) - [`VariableDFG`](@ref) - [`FactorDFG`](@ref) -## DFG Full solvable types - -- [`VariableCompute`](@ref) -- [`FactorCompute`](@ref) - ## Additional Offloaded Data Additional, larger data can be associated with variables and factors using keyed blob entries. diff --git a/docs/src/GraphData.md b/docs/src/GraphData.md index 7b438588..fdd7bc08 100644 --- a/docs/src/GraphData.md +++ b/docs/src/GraphData.md @@ -53,9 +53,9 @@ Each variable or factor can have a timestamp associated with it. Tags are a set of symbols that contain identifiers for the variable or factor. -- [`getTags`](@ref) +- [`listTags`](@ref) - [`mergeTags!`](@ref) -- [`removeTags!`](@ref) +- [`deleteTags!`](@ref) - [`emptyTags!`](@ref) @@ -72,52 +72,11 @@ The solvable flag indicates whether the solver should make use of the variable o #### Variable Type -The `variableType` is the underlying inference variable type, such as a Pose2. +The `AbstractStateType` is the underlying inference variable type, such as a Pose2. -- [`getVariableType`](@ref) +- [`getStateKind`](@ref) -#### Packed Parametric Estimates - -Solved graphs contain packed parametric estimates for the variables, which are keyed by the solution (the default is saved as :default). - -For each PPE structure, there are accessors for getting individual values: - -- [`getPPEMax`](@ref) -- [`getPPEMean`](@ref) -- [`getPPESuggested`](@ref) - - -Related functions for getting, adding/updating, and deleting PPE structures: - - -- [`listPPEs`](@ref) -- [`getPPE`](@ref) -- [`addPPE!`](@ref) -- [`updatePPE!`](@ref) -- [`deletePPE!`](@ref) -- [`mergePPEs!`](@ref) - - -Example of PPE operations: - -```julia -# Add a new PPE of type MeanMaxPPE to :x0 -ppe = MeanMaxPPE(:default, [0.0], [0.0], [0.0]) -addPPE!(dfg, :x0, ppe) -@show listPPEs(dfg, :x0) -# Get the data back - note that this is a reference to above. -v = getPPE(dfg, :x0, :default) -# Delete it -deletePPE!(dfg, :x0, :default) -# Update add it -updatePPE!(dfg, :x0, ppe, :default) -# Update update it -updatePPE!(dfg, :x0, ppe, :default) -# Bulk copy PPE's for x0 and x1 -updatePPE!(dfg, [x0], :default) -``` - #### Variable States (Solver Data) Variable `State`s are used by the IncrementalInference/RoME/Caesar solver. @@ -147,23 +106,23 @@ stateBack = getState(dfg, :x0, :parametric) deleteState!(dfg, :x0, :parametric) ``` -#### Metadata +#### Bloblets -Metadata (small data) allows you to assign a dictionary to variables. It is a useful way to -keep small amounts of primative (Strings, Integers, Floats, Bool) data in a variable. As it is stored in the graph +Bloblets allow you to assign a dictionary of key-value [Symbol-String] pairs to nodes. It is a useful way to +keep small amounts of primitive (Strings, Integers, Floats, Bool) data that is stored as a string in a node. As it is stored in the graph itself, large entries will slow the graph down, so if data should exceed a few bytes/kb, it should rather be saved in Blobs. -- [`getMetadata`](@ref) -- [`setMetadata!`](@ref) +- [`getVariableBloblet`](@ref) +- [`addVariableBloblet!`](@ref) Example: ```julia -setMetadata!(x0, Dict("entry"=>"entry value")) -getMetadata(x0) +addVariableBloblet!(dfg, :x0, Bloblet(:bloblet_label,"bloblet value")) +getVariableBloblet(dfg, :x0) ``` #### Big Data @@ -179,23 +138,25 @@ you are working with an in-memory graph, the DFG structure contains the graph it Graphs reside inside a hierarchy made up in the following way: - Agent - - Metadata + - Bloblets - Blobentries - Graph - - Metadata + - Bloblets - Blobentries -This data can be retrieved with the follow functions: - -- [`getAgentMetadata`](@ref) -- [`getGraphMetadata`](@ref) +Agent and Graph bloblets are useful for storing data that is related to the entire graph, and support CRUD operations: +- [`getAgentBloblet`](@ref) +- [`getGraphBloblet`](@ref) -It can be set using the following functions: +- [`addAgentBloblet!`](@ref) +- [`addGraphBloblet!`](@ref) -- [`setAgentMetadata!`](@ref) -- [`setGraphMetadata!`](@ref) +- [`mergeAgentBloblet!`](@ref) +- [`mergeGraphBloblet!`](@ref) +- [`deleteAgentBloblet!`](@ref) +- [`deleteGraphBloblet!`](@ref) Example of using graph-level data: diff --git a/docs/src/services_ref.md b/docs/src/services_ref.md index 808b1fa2..6560e453 100644 --- a/docs/src/services_ref.md +++ b/docs/src/services_ref.md @@ -23,6 +23,18 @@ Modules = [DistributedFactorGraphs] Pages = ["services/CommonAccessors.jl"] ``` +## Common +```@autodocs +Modules = [DistributedFactorGraphs] +Pages = [ + "services/list.jl", + "services/find.jl", + "services/Tags.jl", + "entities/Bloblet.jl", + "services/Bloblet.jl", +] +``` + ## DFG Variable Accessors CRUD and SET opperations ```@autodocs diff --git a/src/DataBlobs/services/BlobEntry.jl b/src/DataBlobs/services/BlobEntry.jl index c55e9661..b5bbfd01 100644 --- a/src/DataBlobs/services/BlobEntry.jl +++ b/src/DataBlobs/services/BlobEntry.jl @@ -306,7 +306,7 @@ function gatherBlobentries( labelFilter = variableLabelFilter, ) return map(vls) do vl - return vl => getBlobentries(dfg, vl; labelFilter, blobIdFilter) + return vl => getVariableBlobentries(dfg, vl; labelFilter, blobIdFilter) end end const collectBlobentries = gatherBlobentries diff --git a/src/DataBlobs/services/BlobWrappers.jl b/src/DataBlobs/services/BlobWrappers.jl index 8aa6840f..b7d68dc6 100644 --- a/src/DataBlobs/services/BlobWrappers.jl +++ b/src/DataBlobs/services/BlobWrappers.jl @@ -70,7 +70,7 @@ function loadBlob_Variable( # hashfunction = sha256, # checkhash::Bool = true, ) - entry = getBlobentry(dfg, variable_label, entry_label) + entry = getVariableBlobentry(dfg, variable_label, entry_label) blob = getBlob(dfg, entry) # checkhash && assertHash(de, db; hashfunction) return entry, blob @@ -82,7 +82,7 @@ function saveBlob_Variable!( blob::Vector{UInt8}, entry::Blobentry, ) - addBlobentry!(dfg, variable_label, entry) + addVariableBlobentry!(dfg, variable_label, entry) addBlob!(dfg, entry, blob) return entry end @@ -100,8 +100,8 @@ function saveBlob_Variable!( end function deleteBlob_Variable!(dfg::AbstractDFG, variable_label::Symbol, entry_label::Symbol) - entry = getBlobentry(dfg, variable_label, entry_label) - deleteBlobentry!(dfg, variable_label, entry_label) + entry = getVariableBlobentry(dfg, variable_label, entry_label) + deleteVariableBlobentry!(dfg, variable_label, entry_label) deleteBlob!(dfg, entry) return 2 end diff --git a/src/Deprecated.jl b/src/Deprecated.jl index 3246064e..33ec94f1 100644 --- a/src/Deprecated.jl +++ b/src/Deprecated.jl @@ -4,9 +4,6 @@ export FactorCompute const FactorCompute = FactorDFG -""" -Types valid for small data. -""" const MetadataTypes = Union{ Int, Float64, @@ -135,18 +132,10 @@ function getVariableTypeName(v::VariableSummary) return v.statetype end -""" - $(SIGNATURES) -Get the Metadata entry at `key` for variable `label` in `dfg` -""" function getMetadata(dfg::AbstractDFG, label::Symbol, key::Symbol) return getVariable(dfg, label).smallData[key] end -""" - $(SIGNATURES) -Add a Metadata pair `key=>value` for variable `label` in `dfg` -""" function addMetadata!(dfg::AbstractDFG, label::Symbol, pair::Pair{Symbol, <:MetadataTypes}) v = getVariable(dfg, label) haskey(v.smallData, pair.first) && throw(LabelExistsError("Metadata", pair.first)) @@ -155,10 +144,6 @@ function addMetadata!(dfg::AbstractDFG, label::Symbol, pair::Pair{Symbol, <:Meta return v.smallData #or pair TODO end -""" - $(SIGNATURES) -Update a Metadata pair `key=>value` for variable `label` in `dfg` -""" function updateMetadata!( dfg::AbstractDFG, label::Symbol, @@ -174,10 +159,6 @@ function updateMetadata!( return v.smallData #or pair TODO end -""" - $(SIGNATURES) -Delete a Metadata entry at `key` for variable `label` in `dfg` -""" function deleteMetadata!(dfg::AbstractDFG, label::Symbol, key::Symbol) v = getVariable(dfg, label) pop!(v.smallData, key) @@ -185,19 +166,11 @@ function deleteMetadata!(dfg::AbstractDFG, label::Symbol, key::Symbol) return 1 end -""" - $(SIGNATURES) -List all Metadata keys for a variable `label` in `dfg` -""" function listMetadata(dfg::AbstractDFG, label::Symbol) v = getVariable(dfg, label) return collect(keys(v.smallData)) #or pair TODO end -""" - $(SIGNATURES) -Empty all Metadata from variable `label` in `dfg` -""" function emptyMetadata!(dfg::AbstractDFG, label::Symbol) v = getVariable(dfg, label) empty!(v.smallData) diff --git a/src/DistributedFactorGraphs.jl b/src/DistributedFactorGraphs.jl index ce7067a3..ea10e152 100644 --- a/src/DistributedFactorGraphs.jl +++ b/src/DistributedFactorGraphs.jl @@ -303,8 +303,16 @@ export deleteVariableBloblet! export listVariableBloblets export getAgentBloblet -export getGraphBloblet +export addAgentBloblet! +export mergeAgentBloblet! +export deleteAgentBloblet! +export listAgentBloblets +export getGraphBloblet +export addGraphBloblet! +export mergeGraphBloblet! +export deleteGraphBloblet! +export listGraphBloblets ##------------------------------------------------------------------------------ ## FileDFG ##------------------------------------------------------------------------------ @@ -451,13 +459,13 @@ const unstable_functions::Vector{Symbol} = [ :getVariableTypeName, :getStateKind, :setTimestamp, - :setMetadata!, # no set, use add merge :setAgentMetadata!, :setGraphMetadata!, # :getSolverDataDict,# obsolete :getAddHistory, #Deprecated in v0.28 + :setMetadata!, # no set, use add merge :AbstractRelativeMinimize, :AbstractManifoldMinimize, :AbstractPrior, diff --git a/src/FileDFG/services/FileDFG.jl b/src/FileDFG/services/FileDFG.jl index 6f7bc9e3..9bbc7908 100644 --- a/src/FileDFG/services/FileDFG.jl +++ b/src/FileDFG/services/FileDFG.jl @@ -39,18 +39,18 @@ function saveDFG(folder::AbstractString, dfg::AbstractDFG) map(f -> rm("$varFolder/$f"), readdir(varFolder)) map(f -> rm("$factorFolder/$f"), readdir(factorFolder)) # Variables - @showprogress "saving variables" for v in variables + @showprogress desc = "saving variables" for v in variables # vPacked = packVariable(v) JSON.json("$varFolder/$(v.label).json", v; style = DFGJSONStyle()) end # Factors - @showprogress "saving factors" for f in factors + @showprogress desc = "saving factors" for f in factors JSON.json("$factorFolder/$(f.label).json", f; style = DFGJSONStyle()) end #GraphsDFG nodes @assert isa(dfg, GraphsDFG) "only metadata for GraphsDFG are supported" - p = Progress(4, "Saving DFG Nodes") + p = Progress(4; desc = "Saving DFG Nodes") JSON.json("$savepath/graphroot.json", dfg.graph; style = DFGJSONStyle()) next!(p) JSON.json("$savepath/agent.json", dfg.agent; style = DFGJSONStyle()) @@ -119,7 +119,9 @@ function loadDFG!( variablefiles = readdir(joinpath(loaddir, "variables"); sort = false, join = true) # type instability on `variables` as either `::Vector{Variable}` or `::Vector{VariableCompute{<:}}` (vector of abstract) - variables = @showprogress 1 "loading variables" asyncmap(variablefiles) do file + variables = @showprogress dt=1 desc = "loading variables" asyncmap( + variablefiles, + ) do file v = JSON.parsefile(file, V; style = DFGJSONStyle()) return addVariable!(dfgLoadInto, v) end @@ -128,7 +130,7 @@ function loadDFG!( factorfiles = readdir(joinpath(loaddir, "factors"); sort = false, join = true) - factors = @showprogress 1 "loading factors" asyncmap(factorfiles) do file + factors = @showprogress dt=1 desc = "loading factors" asyncmap(factorfiles) do file f = JSON.parsefile(file, F; style = DFGJSONStyle()) return addFactor!(dfgLoadInto, f) end @@ -137,7 +139,7 @@ function loadDFG!( if isa(dfgLoadInto, GraphsDFG) && getTypeDFGFactors(dfgLoadInto) <: FactorDFG # Finally, rebuild the CCW's for the factors to completely reinflate them - @showprogress 1 "Rebuilding factor solver cache" for factor in factors + @showprogress dt=1 desc = "Rebuilding factor solver cache" for factor in factors rebuildFactorCache!(dfgLoadInto, factor) end end @@ -170,7 +172,7 @@ function loadDFG(file::AbstractString) loaddir = Tar.extract(hdr -> contains(hdr.path, dfgnodenames), tar) close(tar) - progess = Progress(4, "Loading DFG Nodes") + progess = Progress(4; desc = "Loading DFG Nodes") agent = JSON.parsefile(joinpath(loaddir, "agent.json"), Agent; style = DFGJSONStyle()) next!(progess) graph = JSON.parsefile( diff --git a/src/GraphsDFG/services/GraphsDFG.jl b/src/GraphsDFG/services/GraphsDFG.jl index 1922b7b2..55983c75 100644 --- a/src/GraphsDFG/services/GraphsDFG.jl +++ b/src/GraphsDFG/services/GraphsDFG.jl @@ -326,8 +326,9 @@ function listNeighbors( dfg::GraphsDFG, node::AbstractGraphNode; solvable::Union{Nothing, Int} = nothing, + kwargs..., ) - return listNeighbors(dfg, node.label; solvable) + return listNeighbors(dfg, node.label; solvable, kwargs...) end function listNeighbors( @@ -402,8 +403,9 @@ end function getBiadjacencyMatrix( dfg::GraphsDFG; solvable::Union{Nothing, Int} = nothing, - varLabels = listVariables(dfg; solvable), - factLabels = listFactors(dfg; solvable), + solvableFilter = isnothing(solvable) ? nothing : >=(solvable), + varLabels = listVariables(dfg; solvableFilter), + factLabels = listFactors(dfg; solvableFilter), ) varIndex = [dfg.g.labels[s] for s in varLabels] factIndex = [dfg.g.labels[s] for s in factLabels] diff --git a/src/entities/Bloblet.jl b/src/entities/Bloblet.jl index 0eb9029a..854060a0 100644 --- a/src/entities/Bloblet.jl +++ b/src/entities/Bloblet.jl @@ -50,6 +50,9 @@ function getBloblet(node, label::Symbol) return refBloblets(node)[label] end +""" + $(SIGNATURES) +""" function getBloblets(node) return collect(values(refBloblets(node))) end diff --git a/src/entities/DFGFactor.jl b/src/entities/DFGFactor.jl index f31e45b4..3c01cb38 100644 --- a/src/entities/DFGFactor.jl +++ b/src/entities/DFGFactor.jl @@ -61,7 +61,7 @@ StructUtils.@kwarg struct FactorDFG{T <: AbstractObservation, N} <: AbstractGrap Accessor: [`getLabel`](@ref)""" label::Symbol """Factor tags, e.g [:FACTOR]. - Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" + Accessors: [`listTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" tags::Set{Symbol} = Set{Symbol}([:FACTOR]) """Ordered list of the neighbor variables. Accessors: [`getVariableOrder`](@ref)""" @@ -222,7 +222,7 @@ $(TYPEDFIELDS) Accessor: [`getLabel`](@ref)""" label::Symbol """Factor tags, e.g [:FACTOR]. - Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" + Accessors: [`listTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" tags::Set{Symbol} """Ordered list of the neighbor variables. Accessors: [`getVariableOrder`](@ref)""" @@ -258,7 +258,7 @@ $(TYPEDFIELDS) Accessor: [`getLabel`](@ref)""" label::Symbol """Factor tags, e.g [:FACTOR]. - Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" + Accessors: [`listTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" tags::Set{Symbol} """Ordered list of the neighbor variables. Accessors: [`getVariableOrder`](@ref)""" diff --git a/src/entities/DFGVariable.jl b/src/entities/DFGVariable.jl index c035ab57..3d2ff682 100644 --- a/src/entities/DFGVariable.jl +++ b/src/entities/DFGVariable.jl @@ -147,13 +147,13 @@ $(TYPEDFIELDS) # steadytime::Union{Nothing, Nanosecond} = nothing #NOTE changed to TimeDateZone in v0.29 #nstime::String = "0" #NOTE different uses, as 0-999_999 nanosecond part of timestamp now in timestamp, as steady timestamp now in steadytime """Variable tags, e.g [:POSE, :VARIABLE, and :LANDMARK]. - Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" + Accessors: [`listTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" tags::Set{Symbol} = Set{Symbol}() """Dictionary of state data. May be a subset of all solutions if a solver label was specified in the get call. Accessors: [`addState!`](@ref), [`mergeState!`](@ref), and [`deleteState!`](@ref)""" states::OrderedDict{Symbol, State{T, P, N}} = OrderedDict{Symbol, State{T, P, N}}() #NOTE field renamed from solverDataDict in v0.29 """Dictionary of small data associated with this variable. - Accessors: [`getBloblet`](@ref), [`setBloblet!`](@ref)""" + Accessors: [`getBloblet`](@ref), [`addBloblet!`](@ref)""" bloblets::Bloblets = Bloblets() #NOTE changed from smallData in v0.29 """Dictionary of large data associated with this variable. Accessors: [`addBlobentry!`](@ref), [`getBlobentry`](@ref), [`mergeBlobentry!`](@ref), and [`deleteBlobentry!`](@ref)""" @@ -289,7 +289,7 @@ $(TYPEDFIELDS) Accessors: [`getTimestamp`](@ref)""" timestamp::TimeDateZone """Variable tags, e.g [:POSE, :VARIABLE, and :LANDMARK]. - Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" + Accessors: [`listTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" tags::Set{Symbol} """Symbol for the state type for the underlying variable.""" statetype::Symbol @@ -315,7 +315,7 @@ Base.@kwdef struct VariableSkeleton <: AbstractGraphVariable Accessor: [`getLabel`](@ref)""" label::Symbol """Variable tags, e.g [:POSE, :VARIABLE, and :LANDMARK]. - Accessors: [`getTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" + Accessors: [`listTags`](@ref), [`mergeTags!`](@ref), and [`deleteTags!`](@ref)""" tags::Set{Symbol} = Set{Symbol}() end diff --git a/src/services/AbstractDFG.jl b/src/services/AbstractDFG.jl index 257a2929..e57791f0 100644 --- a/src/services/AbstractDFG.jl +++ b/src/services/AbstractDFG.jl @@ -358,10 +358,10 @@ function getVariable(dfg::AbstractDFG, label::Symbol, solveKey::Symbol) # function getVariable(dfg::AbstractDFG, label::Symbol; stateLabelFilter::Union{Nothing, ...} = nothing) var = getVariable(dfg, label) - if isa(var, VariableCompute) && !haskey(var.states, solveKey) + if isa(var, VariableDFG) && !haskey(var.states, solveKey) throw(LabelNotFoundError("VariableNode", solveKey)) - elseif !isa(var, VariableCompute) - @warn "getVariable(dfg, label, solveKey) only supported for type VariableCompute." + elseif !isa(var, VariableDFG) + @warn "getVariable(dfg, label, solveKey) only supported for type VariableDFG." end return var @@ -549,9 +549,7 @@ function deepcopyGraph( graphLabel::Symbol = Symbol(getGraphLabel(sourceDFG), "_cp_$(string(uuid4())[1:6])"), kwargs..., ) where {T <: AbstractDFG} - ginfo = getDFGInfo(sourceDFG) - - destDFG = T(; ginfo..., graphLabel) + destDFG = T(; graph = sourceDFG.graph, agent = sourceDFG.agent, graphLabel) copyGraph!( destDFG, sourceDFG, diff --git a/src/services/Bloblet.jl b/src/services/Bloblet.jl index 1aadb20e..8242c068 100644 --- a/src/services/Bloblet.jl +++ b/src/services/Bloblet.jl @@ -1,23 +1,44 @@ ## ============================================================================== ## Variable Bloblets ## ============================================================================== +""" + $(SIGNATURES) +""" function getVariableBloblet(dfg::GraphsDFG, var_label::Symbol, label::Symbol) return getBloblet(getVariable(dfg, var_label), label) end +""" + $(SIGNATURES) +""" function getVariableBloblets(dfg::GraphsDFG, var_label::Symbol) return getBloblets(getVariable(dfg, var_label)) end +""" + $(SIGNATURES) +""" function addVariableBloblet!(dfg::GraphsDFG, var_label::Symbol, bloblet::Bloblet) return addBloblet!(getVariable(dfg, var_label), bloblet) end + +""" + $(SIGNATURES) +""" function addVariableBloblets!(dfg::GraphsDFG, var_label::Symbol, bloblets::Vector{Bloblet}) return addBloblets!(getVariable(dfg, var_label), bloblets) end + +""" + $(SIGNATURES) +""" function mergeVariableBloblet!(dfg::GraphsDFG, var_label::Symbol, bloblet::Bloblet) return mergeBloblet!(getVariable(dfg, var_label), bloblet) end + +""" + $(SIGNATURES) +""" function mergeVariableBloblets!( dfg::GraphsDFG, var_label::Symbol, @@ -25,12 +46,24 @@ function mergeVariableBloblets!( ) return mergeBloblets!(getVariable(dfg, var_label), bloblets) end + +""" + $(SIGNATURES) +""" function deleteVariableBloblet!(dfg::GraphsDFG, var_label::Symbol, label::Symbol) return deleteBloblet!(getVariable(dfg, var_label), label) end + +""" + $(SIGNATURES) +""" function deleteVariableBloblets!(dfg::GraphsDFG, var_label::Symbol, labels::Vector{Symbol}) return deleteBloblets!(getVariable(dfg, var_label), labels) end + +""" + $(SIGNATURES) +""" function listVariableBloblets(dfg::GraphsDFG, var_label::Symbol) return listBloblets(getVariable(dfg, var_label)) end @@ -38,30 +71,65 @@ end ## ============================================================================== ## Factor Bloblets ## ============================================================================== +""" + $(SIGNATURES) +""" function getFactorBloblet(dfg::GraphsDFG, fac_label::Symbol, label::Symbol) return getBloblet(getFactor(dfg, fac_label), label) end + +""" + $(SIGNATURES) +""" function getFactorBloblets(dfg::GraphsDFG, fac_label::Symbol) return getBloblets(getFactor(dfg, fac_label)) end + +""" + $(SIGNATURES) +""" function addFactorBloblet!(dfg::GraphsDFG, fac_label::Symbol, bloblet::Bloblet) return addBloblet!(getFactor(dfg, fac_label), bloblet) end + +""" + $(SIGNATURES) +""" function addFactorBloblets!(dfg::GraphsDFG, fac_label::Symbol, bloblets::Vector{Bloblet}) return addBloblets!(getFactor(dfg, fac_label), bloblets) end + +""" + $(SIGNATURES) +""" function mergeFactorBloblet!(dfg::GraphsDFG, fac_label::Symbol, bloblet::Bloblet) return mergeBloblet!(getFactor(dfg, fac_label), bloblet) end + +""" + $(SIGNATURES) +""" function mergeFactorBloblets!(dfg::GraphsDFG, fac_label::Symbol, bloblets::Vector{Bloblet}) return mergeBloblets!(getFactor(dfg, fac_label), bloblets) end + +""" + $(SIGNATURES) +""" function deleteFactorBloblet!(dfg::GraphsDFG, fac_label::Symbol, label::Symbol) return deleteBloblet!(getFactor(dfg, fac_label), label) end + +""" + $(SIGNATURES) +""" function deleteFactorBloblets!(dfg::GraphsDFG, fac_label::Symbol, labels::Vector{Symbol}) return deleteBloblets!(getFactor(dfg, fac_label), labels) end + +""" + $(SIGNATURES) +""" function listFactorBloblets(dfg::GraphsDFG, fac_label::Symbol) return listBloblets(getFactor(dfg, fac_label)) end @@ -69,41 +137,91 @@ end ##============================================================================== ## Agent Bloblets ##============================================================================== - +""" + $(SIGNATURES) +""" getAgentBloblet(dfg::GraphsDFG, label::Symbol) = getBloblet(dfg.agent, label) +""" + $(SIGNATURES) +""" addAgentBloblet!(dfg::GraphsDFG, bloblet::Bloblet) = addBloblet!(dfg.agent, bloblet) +""" + $(SIGNATURES) +""" mergeAgentBloblet!(dfg::GraphsDFG, bloblet::Bloblet) = mergeBloblet!(dfg.agent, bloblet) +""" + $(SIGNATURES) +""" deleteAgentBloblet!(dfg::GraphsDFG, label::Symbol) = deleteBloblet!(dfg.agent, label) - +""" + $(SIGNATURES) +""" getAgentBloblets(dfg::GraphsDFG) = getBloblets(dfg.agent) +""" + $(SIGNATURES) +""" function addAgentBloblets!(dfg::GraphsDFG, bloblets::Vector{Bloblet}) return addBloblets!(dfg.agent, bloblets) end +""" + $(SIGNATURES) +""" function mergeAgentBloblets!(dfg::GraphsDFG, bloblets::Vector{Bloblet}) return mergeBloblets!(dfg.agent, bloblets) end +""" + $(SIGNATURES) +""" function deleteAgentBloblets!(dfg::GraphsDFG, labels::Vector{Symbol}) return deleteBloblets!(dfg.agent, labels) end +""" + $(SIGNATURES) +""" listAgentBloblets(dfg::GraphsDFG) = listBloblets(dfg.agent) ##============================================================================== ## Graph Bloblets ##============================================================================== - +""" + $(SIGNATURES) +""" getGraphBloblet(dfg::GraphsDFG, label::Symbol) = getBloblet(dfg.graph, label) +""" + $(SIGNATURES) +""" addGraphBloblet!(dfg::GraphsDFG, bloblet::Bloblet) = addBloblet!(dfg.graph, bloblet) +""" + $(SIGNATURES) +""" mergeGraphBloblet!(dfg::GraphsDFG, bloblet::Bloblet) = mergeBloblet!(dfg.graph, bloblet) +""" + $(SIGNATURES) +""" deleteGraphBloblet!(dfg::GraphsDFG, label::Symbol) = deleteBloblet!(dfg.graph, label) - +""" + $(SIGNATURES) +""" getGraphBloblets(dfg::GraphsDFG) = getBloblets(dfg.graph) +""" + $(SIGNATURES) +""" function addGraphBloblets!(dfg::GraphsDFG, bloblets::Vector{Bloblet}) return addBloblets!(dfg.graph, bloblets) end +""" + $(SIGNATURES) +""" function mergeGraphBloblets!(dfg::GraphsDFG, bloblets::Vector{Bloblet}) return mergeBloblets!(dfg.graph, bloblets) end +""" + $(SIGNATURES) +""" function deleteGraphBloblets!(dfg::GraphsDFG, labels::Vector{Symbol}) return deleteBloblets!(dfg.graph, labels) end +""" + $(SIGNATURES) +""" listGraphBloblets(dfg::GraphsDFG) = listBloblets(dfg.graph) diff --git a/src/services/CommonAccessors.jl b/src/services/CommonAccessors.jl index 2d73b829..23186a64 100644 --- a/src/services/CommonAccessors.jl +++ b/src/services/CommonAccessors.jl @@ -48,7 +48,9 @@ Variables or factors may or may not be 'solvable', depending on a user definitio Related: - isSolveInProgress """ -getSolvable(node::Union{VariableDFG, FactorDFG}) = node.solvable[] +function getSolvable(node::Union{VariableDFG, VariableSummary, FactorDFG, FactorSummary}) + return node.solvable[] +end """ $SIGNATURES diff --git a/src/services/CompareUtils.jl b/src/services/CompareUtils.jl index d60793c8..169320a5 100644 --- a/src/services/CompareUtils.jl +++ b/src/services/CompareUtils.jl @@ -321,13 +321,13 @@ function compareFactor( ) @debug "compareFactor 3/5" TP - #FIXME is measurement stil in use and should it be checked, skipping for now - if false # !(:measurement in skip) + #FIXME is measurement stil in use + if !(:measurement in skip) TP = TP & ( skipsamples || compareAll( - getSolverData(A).fnc.measurement, - getSolverData(B).fnc.measurement; + getCache(A).measurement, + getCache(B).measurement; show = show, skip = skip, ) @@ -335,26 +335,27 @@ function compareFactor( end @debug "compareFactor 4/5" TP #FIXME is varValsAll stil in use and should it be checked, skipping for now - if false #!(:varValsAll in skip) && hasfield(typeof(getSolverData(A).fnc), :varValsAll) + if !(:varValsAll in skip) && hasfield(typeof(getCache(A)), :varValsAll) TP = TP & ( skipcompute || compareAll( - getSolverData(A).fnc.varValsAll, - getSolverData(B).fnc.varValsAll; + getCache(A).varValsAll, + getCache(B).varValsAll; show = show, skip = skip, ) ) end @debug "compareFactor 5/5" TP - #FIXME is varidx stil in use and should it be checked, skipping for now - if false #!(:varidx in skip) && hasfield(typeof(getSolverData(A).fnc), :varidx) && - getSolverData(A).fnc.varidx isa Base.RefValue + #FIXME is varidx stil in use and should it be checked + if !(:varidx in skip) && + hasfield(typeof(getCache(A)), :varidx) && + getCache(A).varidx isa Base.RefValue TP = TP & ( skipcompute || compareAll( - getSolverData(A).fnc.varidx[], - getSolverData(B).fnc.varidx[]; + getCache(A).varidx[], + getCache(B).varidx[]; show = show, skip = skip, ) diff --git a/src/services/Tags.jl b/src/services/Tags.jl index c544be32..202c510d 100644 --- a/src/services/Tags.jl +++ b/src/services/Tags.jl @@ -15,7 +15,9 @@ end ##============================================================================== ## TAGS as a set, list, merge, remove, empty ##============================================================================== - +""" +$SIGNATURES +""" listTags(node) = collect(refTags(node)) """ diff --git a/src/services/find.jl b/src/services/find.jl index 317249cf..9dad8bda 100644 --- a/src/services/find.jl +++ b/src/services/find.jl @@ -61,7 +61,7 @@ function findVariableNearTimestamp( # # get the variable labels based on filters # syms = listVariables(dfg, regexFilter, tags=tags, solvable=solvable) - syms = listVariables(dfg, regexFilter; tags = tags, solvable = solvable) + syms = listVariables(dfg, regexFilter; tags = tags, solvableFilter = >=(solvable)) # compile timestamps with label # vars = map( x->getVariable(dfg, x), syms ) timeset = map(x -> (getTimestamp(getVariable(dfg, x)), x), syms) diff --git a/test/iifCompareTests.jl b/test/iifCompareTests.jl index 9eda5c8f..cbc381f7 100644 --- a/test/iifCompareTests.jl +++ b/test/iifCompareTests.jl @@ -75,7 +75,7 @@ using Test skip = [:fullvariables], ) - @test_broken !compareSimilarFactors(fg, fg2; skipsamples = true, skipcompute = false) + @test !compareSimilarFactors(fg, fg2; skipsamples = true, skipcompute = false) @test compareFactorGraphs( fg, diff --git a/test/runtests.jl b/test/runtests.jl index d5427648..9a6c84b6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -63,7 +63,7 @@ DFG.@usingDFG true end end - if get(ENV, "IIF_TEST", "false") == "true" + if get(ENV, "IIF_TEST", "true") == "true" # Switch to our upstream test branch. #FIXME This is a temporary fix to use the develop branch of AMP. diff --git a/test/testBlocks.jl b/test/testBlocks.jl index fac5e42e..b274b9f4 100644 --- a/test/testBlocks.jl +++ b/test/testBlocks.jl @@ -255,7 +255,7 @@ function DFGVariableSCA() TestVariableType1(); tags = v1_tags, solvable = 0, - states = Dict(:default => State{TestVariableType1}(; label = :default)), + states = OrderedDict(:default => State{TestVariableType1}(; label = :default)), bloblets = DFG.Bloblets(:small => DFG.Bloblet(:small, "data")), ) v2 = VariableCompute( @@ -274,7 +274,7 @@ function DFGVariableSCA() TestVariableType1(); tags = v1_tags, solvable = 0, - states = Dict(:default => State{TestVariableType1}(; label = :default)), + states = OrderedDict(:default => State{TestVariableType1}(; label = :default)), ) # v1.states[:default].val[1] = [0.0;] @@ -481,7 +481,7 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) #TODO decide if this should be @error or other type @test_throws LabelNotFoundError getVariable(fg, :a, :missingfoo) else - @test_logs (:warn, r"supported for type VariableCompute") getVariable( + @test_logs (:warn, r"supported for type VariableDFG") getVariable( fg, :a, :missingfoo, @@ -854,29 +854,29 @@ function blobsStoresTestBlock!(fg) var2 = getVariable(fg, :b) @test addBlobentry!(var1, de1) == de1 mergeVariable!(fg, var1) - @test addBlobentry!(fg, :a, de2) == de2 + @test addVariableBlobentry!(fg, :a, de2) == de2 @test_throws LabelExistsError addBlobentry!(var1, de1) - @test de2 in getBlobentries(fg, var1.label) + @test de2 in getVariableBlobentries(fg, var1.label) #get @test deepcopy(de1) == getBlobentry(var1, :label1) - @test deepcopy(de2) == getBlobentry(fg, :a, :label2) + @test deepcopy(de2) == getVariableBlobentry(fg, :a, :label2) @test_throws LabelNotFoundError getBlobentry(var2, :label1) - @test_throws LabelNotFoundError getBlobentry(fg, :b, :label1) + @test_throws LabelNotFoundError getVariableBlobentry(fg, :b, :label1) #update - @test mergeBlobentry!(fg, :a, de2_update) == 1 - @test deepcopy(de2_update) == getBlobentry(fg, :a, :label2) - @test mergeBlobentry!(fg, :b, de2_update) == 1 + @test mergeVariableBlobentry!(fg, :a, de2_update) == 1 + @test deepcopy(de2_update) == getVariableBlobentry(fg, :a, :label2) + @test mergeVariableBlobentry!(fg, :b, de2_update) == 1 #list entries = getVariableBlobentries(fg, :a) @test length(entries) == 2 @test issetequal(map(e -> e.label, entries), [:label1, :label2]) - @test length(getBlobentries(fg, :b)) == 1 + @test length(getVariableBlobentries(fg, :b)) == 1 - @test issetequal(listBlobentries(fg, :a), [:label1, :label2]) - @test listBlobentries(fg, :b) == Symbol[:label2] + @test issetequal(listVariableBlobentries(fg, :a), [:label1, :label2]) + @test listVariableBlobentries(fg, :b) == Symbol[:label2] # test collecting blobentries with filters gathered = DFG.gatherBlobentries( @@ -885,13 +885,13 @@ function blobsStoresTestBlock!(fg) labelFilter = contains("1"), ) @test first(gathered[1]) == :a - @test last(gathered[1])[1] == getBlobentry(fg, :a, :label1) + @test last(gathered[1])[1] == getVariableBlobentry(fg, :a, :label1) #delete - @test deleteBlobentry!(fg, var1.label, de1.label) == 1 - @test listBlobentries(fg, var1.label) == Symbol[:label2] + @test deleteVariableBlobentry!(fg, var1.label, de1.label) == 1 + @test listVariableBlobentries(fg, var1.label) == Symbol[:label2] #delete from dfg - @test deleteBlobentry!(fg, :a, :label2) == 1 + @test deleteVariableBlobentry!(fg, :a, :label2) == 1 var1 = getVariable(fg, :a) @test listBlobentries(var1) == Symbol[] @@ -928,7 +928,7 @@ function blobsStoresTestBlock!(fg) # on Variable newentry = DFG.saveBlob_Variable!(fg, :a, testData, :testing, fs.label) @test_throws DFG.LabelExistsError DFG.saveBlob_Variable!(fg, :a, testData, :testing) - @test :testing in listBlobentries(fg, :a) + @test :testing in listVariableBlobentries(fg, :a) be, blob = DFG.loadBlob_Variable(fg, :a, :testing) @test newentry == be @test blob == testData @@ -1008,39 +1008,45 @@ function testGroup!(fg, v1, v2, f0, f1) @test_skip varNearTs[1][1] == [:b] ## SORT copied from CRUD - @test all(getVariables(fg, r"a") .== [getVariable(fg, v1.label)]) - @test all(getVariables(fg; solvable = 1) .== [getVariable(fg, v2.label)]) - @test getVariables(fg, r"a"; solvable = 1) == [] - @test getVariables(fg; tags = [:LANDMARK])[1] == getVariable(fg, v2.label) - - @test getFactors(fg, r"nope") == [] - @test issetequal(getLabel.(getFactors(fg; solvable = 1)), [:af1, :abf1]) - @test getFactors(fg; solvable = 2) == [] - @test getFactors(fg; tags = [:tag1])[1] == f1 - @test getFactors(fg; tags = [:PRIOR])[1] == f0 + @test all( + getVariables(fg; labelFilter = contains(r"a")) .== [getVariable(fg, v1.label)], + ) + @test all(getVariables(fg; solvableFilter = >=(1)) .== [getVariable(fg, v2.label)]) + @test getVariables(fg; labelFilter = contains(r"a"), solvableFilter = >=(1)) == [] + @test getVariables(fg; tagsFilter = ⊇([:LANDMARK]))[1] == getVariable(fg, v2.label) + + @test getFactors(fg; labelFilter = contains(r"nope")) == [] + @test issetequal(getLabel.(getFactors(fg; solvableFilter = >=(1))), [:af1, :abf1]) + @test getFactors(fg; solvableFilter = >=(2)) == [] + @test getFactors(fg; tagsFilter = ⊇([:tag1]))[1] == f1 + @test getFactors(fg; tagsFilter = ⊇([:PRIOR]))[1] == f0 ##/SORT # Additional testing for https://github.com/JuliaRobotics/DistributedFactorGraphs.jl/issues/201 # list solvable - @test symdiff([:a, :b], listVariables(fg; solvable = 0)) == [] - @test listVariables(fg; solvable = 1) == [:b] + @test symdiff([:a, :b], listVariables(fg; solvableFilter = >=(0))) == [] + @test listVariables(fg; solvableFilter = >=(1)) == [:b] - @test issetequal(listFactors(fg; solvable = 1), [:af1, :abf1]) - @test issetequal(listFactors(fg; solvable = 0), [:af1, :abf1]) - @test all([f in [f0, f1] for f in getFactors(fg; solvable = 1)]) + @test issetequal(listFactors(fg; solvableFilter = >=(1)), [:af1, :abf1]) + @test issetequal(listFactors(fg; solvableFilter = >=(0)), [:af1, :abf1]) + @test all([f in [f0, f1] for f in getFactors(fg; solvableFilter = >=(1))]) @test lsf(fg, :b) == [f1.label] # Tags - @test ls(fg; tags = [:POSE]) == [] - @test issetequal(ls(fg; tags = [:POSE, :LANDMARK]), ls(fg; tags = [:VARIABLE])) + @test ls(fg; tagsFilter = ⊇([:POSE])) == [] + @test issetequal( + ls(fg; tagsFilter = !isdisjoint([:POSE, :LANDMARK])), + ls(fg; tagsFilter = ⊇([:VARIABLE])), + ) - @test lsf(fg; tags = [:NONE]) == [] - @test lsf(fg; tags = [:PRIOR]) == [:af1] + @test lsf(fg; tagsFilter = !isdisjoint([:NONE])) == [] + @test lsf(fg; tagsFilter = ⊇([:NONE])) == [] + @test lsf(fg; tagsFilter = ⊇([:PRIOR])) == [:af1] # Regexes - @test ls(fg, r"a") == [v1.label] - @test lsf(fg, r"abf*") == [f1.label] + @test ls(fg, labelFilter = contains(r"a")) == [v1.label] + @test lsf(fg, labelFilter = contains(r"abf*")) == [f1.label] #TODO test filters and options # regexFilter::Union{Nothing, Regex}=nothing; @@ -1196,13 +1202,13 @@ function AdjacencyMatricesTestBlock(fg) # Only do solvable tests on VariableCompute if isa(getVariable(fg, :a), VariableCompute) # Filtered - REF DFG #201 - adjMat, v_ll, f_ll = getBiadjacencyMatrix(fg; solvable = 0) + adjMat, v_ll, f_ll = getBiadjacencyMatrix(fg; solvableFilter = >=(0)) @test size(adjMat) == (1, 3) @test symdiff(v_ll, [:a, :b, :orphan]) == Symbol[] @test symdiff(f_ll, [:abf1]) == Symbol[] # sparse - adjMat, v_ll, f_ll = getBiadjacencyMatrix(fg; solvable = 1) + adjMat, v_ll, f_ll = getBiadjacencyMatrix(fg; solvableFilter = >=(1)) @test size(adjMat) == (1, 2) @test issetequal(v_ll, [:a, :b]) @test f_ll == [:abf1] @@ -1295,13 +1301,16 @@ function GettingNeighbors(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = Facto # Solvable #TODO if not a GraphsDFG with and summary or skeleton if VARTYPE == VariableCompute - @test listNeighbors(dfg, :x5; solvable = 2) == Symbol[] - @test issetequal(listNeighbors(dfg, :x5; solvable = 0), [:x4x5f1, :x5x6f1]) + @test listNeighbors(dfg, :x5; solvableFilter = >=(2)) == Symbol[] + @test issetequal( + listNeighbors(dfg, :x5; solvableFilter = >=(0)), + [:x4x5f1, :x5x6f1], + ) @test issetequal(listNeighbors(dfg, :x5), [:x4x5f1, :x5x6f1]) - @test listNeighbors(dfg, :x7x8f1; solvable = 0) == [:x7, :x8] - @test listNeighbors(dfg, :x7x8f1; solvable = 1) == [:x7] - @test listNeighbors(dfg, verts[1]; solvable = 0) == [:x1x2f1] - @test listNeighbors(dfg, verts[1]; solvable = 2) == Symbol[] + @test listNeighbors(dfg, :x7x8f1; solvableFilter = >=(0)) == [:x7, :x8] + @test listNeighbors(dfg, :x7x8f1; solvableFilter = >=(1)) == [:x7] + @test listNeighbors(dfg, verts[1]; solvableFilter = >=(0)) == [:x1x2f1] + @test listNeighbors(dfg, verts[1]; solvableFilter = >=(2)) == Symbol[] @test listNeighbors(dfg, verts[1]) == [:x1x2f1] end end