diff --git a/docs/src/DataStructure.md b/docs/src/DataStructure.md index 65f0c811..fbcc5675 100644 --- a/docs/src/DataStructure.md +++ b/docs/src/DataStructure.md @@ -17,7 +17,7 @@ Accessible properties for each of the variable structures: |---------------------|-------|-----------|------|-----------|-----------|----------|-------------|----------|--------------| | VariableSkeleton | X | | X | | | | | | | | VariableSummary | X | X | X | X | Symbol | | | | X | -| VariableCompute | X | X | X | X | X | X | X | X | X | +| VariableDFG | X | X | X | X | X | X | X | X | X | Accessible properties for each of the factor structures: diff --git a/docs/src/GraphData.md b/docs/src/GraphData.md index fdd7bc08..3b710564 100644 --- a/docs/src/GraphData.md +++ b/docs/src/GraphData.md @@ -161,6 +161,6 @@ Agent and Graph bloblets are useful for storing data that is related to the enti Example of using graph-level data: ```julia -setAgentMetadata!(dfg, Dict(:a => "Hello")) -getAgentMetadata(dfg) +addAgentBloblet!(dfg, Bloblet(:status, "ready")) +getAgentBloblet(dfg, :status) ``` diff --git a/src/DataBlobs/entities/BlobEntry.jl b/src/DataBlobs/entities/BlobEntry.jl index dae68d3d..14a6e8b1 100644 --- a/src/DataBlobs/entities/BlobEntry.jl +++ b/src/DataBlobs/entities/BlobEntry.jl @@ -113,23 +113,6 @@ function Base.getproperty(x::Blobentry, f::Symbol) end end -function Base.setproperty!(x::Blobentry, f::Symbol, val) - if f == :blobId - @warn "Blobentry field :blobId has been renamed to :blobid" - setfield!(x, :blobid, val) - elseif f == :mimeType - @warn "Blobentry field :mimeType has been renamed to :mimetype" - setfield!(x, :mimetype, val) - elseif f == :_version - @warn "Blobentry field :_version has been renamed to :version" - setfield!(x, :version, val) - elseif f in [:id, :createdTimestamp, :lastUpdatedTimestamp, :hash] - error("Blobentry field $f has been deprecated") - else - setfield!(x, f, val) - end -end - const Blobentries = OrderedDict{Symbol, Blobentry} function StructUtils.lower(entries::Blobentries) diff --git a/src/DataBlobs/services/BlobEntry.jl b/src/DataBlobs/services/BlobEntry.jl index b5bbfd01..fc4d7592 100644 --- a/src/DataBlobs/services/BlobEntry.jl +++ b/src/DataBlobs/services/BlobEntry.jl @@ -13,11 +13,11 @@ end function getBlobentries( node; labelFilter::Union{Nothing, Function} = nothing, - blobIdFilter::Union{Nothing, Function} = nothing, + blobidFilter::Union{Nothing, Function} = nothing, ) entries = collect(values(refBlobentries(node))) filterDFG!(entries, labelFilter, getLabel) - filterDFG!(entries, blobIdFilter, x -> string(x.blobid)) + filterDFG!(entries, blobidFilter, x -> string(x.blobid)) return entries end @@ -195,6 +195,52 @@ function listModelBlobentries end function hasGraphBlobentry end function hasAgentBlobentry end function hasModelBlobentry end + +##============================================================================== +## Default Variable/Factor implementations +##============================================================================== + +function getVariableBlobentry(dfg::AbstractDFG, variableLabel::Symbol, label::Symbol) + return getBlobentry(getVariable(dfg, variableLabel), label) +end + +function getVariableBlobentries( + dfg::AbstractDFG, + variableLabel::Symbol; + labelFilter::Union{Nothing, Function} = nothing, + blobidFilter::Union{Nothing, Function} = nothing, +) + return getBlobentries(getVariable(dfg, variableLabel); labelFilter, blobidFilter) +end + +function listVariableBlobentries(dfg::AbstractDFG, variableLabel::Symbol) + return listBlobentries(getVariable(dfg, variableLabel)) +end + +function hasVariableBlobentry(dfg::AbstractDFG, variableLabel::Symbol, label::Symbol) + return hasBlobentry(getVariable(dfg, variableLabel), label) +end + +function getFactorBlobentry(dfg::AbstractDFG, factorLabel::Symbol, label::Symbol) + return getBlobentry(getFactor(dfg, factorLabel), label) +end + +function getFactorBlobentries( + dfg::AbstractDFG, + factorLabel::Symbol; + labelFilter::Union{Nothing, Function} = nothing, + blobidFilter::Union{Nothing, Function} = nothing, +) + return getBlobentries(getFactor(dfg, factorLabel); labelFilter, blobidFilter) +end + +function listFactorBlobentries(dfg::AbstractDFG, factorLabel::Symbol) + return listBlobentries(getFactor(dfg, factorLabel)) +end + +function hasFactorBlobentry(dfg::AbstractDFG, factorLabel::Symbol, label::Symbol) + return hasBlobentry(getFactor(dfg, factorLabel), label) +end ##============================================================================== ## Blobentry [default] bulk operations ##============================================================================== @@ -280,19 +326,10 @@ end ## Blobentry - Helper functions, Lists, etc ##============================================================================== -function getVariableBlobentries( - dfg::AbstractDFG, - variableLabel::Symbol; - labelFilter::Union{Nothing, Function} = nothing, - blobIdFilter::Union{Nothing, Function} = nothing, -) - return getBlobentries(getVariable(dfg, variableLabel); labelFilter, blobIdFilter) -end - function gatherBlobentries( dfg::AbstractDFG; labelFilter::Union{Nothing, Function} = nothing, - blobIdFilter::Union{Nothing, Function} = nothing, + blobidFilter::Union{Nothing, Function} = nothing, solvableFilter::Union{Nothing, Function} = nothing, tagsFilter::Union{Nothing, Function} = nothing, typeFilter::Union{Nothing, Function} = nothing, @@ -306,15 +343,11 @@ function gatherBlobentries( labelFilter = variableLabelFilter, ) return map(vls) do vl - return vl => getVariableBlobentries(dfg, vl; labelFilter, blobIdFilter) + return vl => getVariableBlobentries(dfg, vl; labelFilter, blobidFilter) end end const collectBlobentries = gatherBlobentries -function listVariableBlobentries(dfg::AbstractDFG, label::Symbol) - return listBlobentries(getVariable(dfg, label)) -end - """ $(SIGNATURES) Finds and returns the first blob entry that matches the filter. @@ -324,11 +357,11 @@ Also see: [`getBlobentry`](@ref) function getfirstBlobentry( node; labelFilter::Union{Nothing, Function} = nothing, - blobIdFilter::Union{Nothing, Function} = nothing, + blobidFilter::Union{Nothing, Function} = nothing, sortby::Function = getLabel, sortlt::Function = natural_lt, ) - entries = getBlobentries(node; labelFilter, blobIdFilter) + entries = getBlobentries(node; labelFilter, blobidFilter) if isempty(entries) return nothing else @@ -340,9 +373,9 @@ function getfirstVariableBlobentry( dfg::AbstractDFG, label::Symbol; labelFilter::Union{Nothing, Function} = nothing, - blobIdFilter::Union{Nothing, Function} = nothing, + blobidFilter::Union{Nothing, Function} = nothing, ) - return getfirstBlobentry(getVariable(dfg, label); labelFilter, blobIdFilter) + return getfirstBlobentry(getVariable(dfg, label); labelFilter, blobidFilter) end ## ============================================================================= diff --git a/src/Deprecated.jl b/src/Deprecated.jl index 33ec94f1..54f92e4d 100644 --- a/src/Deprecated.jl +++ b/src/Deprecated.jl @@ -58,11 +58,11 @@ end # isSolvable # """ function getSolveInProgress( - var::Union{VariableCompute, FactorCompute}, + var::Union{VariableDFG, FactorCompute}, solveKey::Symbol = :default, ) # Variable - if var isa VariableCompute + if var isa VariableDFG if haskey(refStates(var), solveKey) return refStates(var)[solveKey].solveInProgress else @@ -76,7 +76,7 @@ end #TODO missing set solveInProgress and graph level accessor function isSolveInProgress( - node::Union{VariableCompute, FactorCompute}, + node::Union{VariableDFG, FactorCompute}, solvekey::Symbol = :default, ) return getSolveInProgress(node, solvekey) > 0 @@ -321,6 +321,12 @@ function updateBlob!(args...) return error("updateBlob! is obsolete as blobid=>Blob pairs are immutable.") end +function setTags!(node, tags::Union{Vector{Symbol}, Set{Symbol}}) + Base.depwarn("setTags! is deprecated, use mergeTags! or addTags! instead.", :setTags!) + node.tags !== tags && empty!(node.tags) + return union!(node.tags, tags) +end + ## ================================================================================ ## Deprecated in v0.28 ##================================================================================= @@ -629,18 +635,18 @@ end function getfirstBlobentry(var::AbstractGraphVariable, blobId::UUID) Base.depwarn( - "getfirstBlobentry(var, blobId) is deprecated, use getfirstBlobentry(var; blobIdFilter = ==(string(blobId))) instead.", + "getfirstBlobentry(var, blobId) is deprecated, use getfirstBlobentry(var; blobidFilter = ==(string(blobId))) instead.", :getfirstBlobentry, ) - return getfirstBlobentry(var; blobIdFilter = ==(string(blobId))) + return getfirstBlobentry(var; blobidFilter = ==(string(blobId))) end function getfirstBlobentry(dfg::AbstractDFG, label::Symbol, blobId::UUID) Base.depwarn( - "getfirstBlobentry(dfg, label, blobId) is deprecated, use getfirstBlobentry(dfg, label; blobIdFilter = ==(string(blobId))) instead.", + "getfirstBlobentry(dfg, label, blobId) is deprecated, use getfirstBlobentry(dfg, label; blobidFilter = ==(string(blobId))) instead.", :getfirstBlobentry, ) - return getfirstBlobentry(dfg, label; blobIdFilter = ==(string(blobId))) + return getfirstBlobentry(dfg, label; blobidFilter = ==(string(blobId))) end function getfirstBlobentry(var::AbstractGraphVariable, key::Regex) diff --git a/src/DistributedFactorGraphs.jl b/src/DistributedFactorGraphs.jl index ea10e152..8afc9ef5 100644 --- a/src/DistributedFactorGraphs.jl +++ b/src/DistributedFactorGraphs.jl @@ -44,7 +44,7 @@ using Tables # used for @defStateType import ManifoldsBase using ManifoldsBase: AbstractManifold, manifold_dimension -export AbstractManifold, manifold_dimension +export AbstractManifold using RecursiveArrayTools: ArrayPartition export ArrayPartition @@ -64,26 +64,30 @@ export AbstractBlobstore, Blobstore export AbstractGraphNode, GraphNode export AbstractGraphVariable, GraphVariable export AbstractGraphFactor, GraphFactor -export AbstractPackedObservation, PackedObservation export AbstractObservation, Observation export AbstractPriorObservation, PriorObservation export AbstractRelativeObservation, RelativeObservation export AbstractFactorCache, FactorCache export AbstractStateType, StateType -export AbstractPackedBelief, PackedBelief ##------------------------------------------------------------------------------ ## Types ##------------------------------------------------------------------------------ #TODO types are not yet stable - also, we might not export types such as VariableCompute # Variables -export VariableCompute, VariableDFG, VariableSummary, VariableSkeleton +export VariableDFG +export VariableSummary +export VariableSkeleton # Factors -export FactorDFG, FactorSummary, FactorSkeleton +export FactorDFG +export FactorSummary +export FactorSkeleton +#TODO Still pending timestamp field name decision export Blobentry export State +export Agent ##------------------------------------------------------------------------------ ## Functions @@ -185,6 +189,17 @@ export hasVariableBlobentry export hasGraphBlobentry export hasAgentBlobentry +export addFactorBlobentry! +export addFactorBlobentries! +export getFactorBlobentry +export getFactorBlobentries +export mergeFactorBlobentry! +export mergeFactorBlobentries! +export deleteFactorBlobentry! +export deleteFactorBlobentries! +export listFactorBlobentries +export hasFactorBlobentry + ##------------------------------------------------------------------------------ ## Blobstores and Blobs ##------------------------------------------------------------------------------ @@ -223,19 +238,15 @@ export GraphsDFG # export addState!, getState, mergeState!, deleteState! # export addStates!, getStates, mergeStates!, deleteStates! -# export addBlobentry!, getBlobentry, mergeBlobentry!, deleteBlobentry! # historic for VariableBlobentry -# export addBlobentries!, getBlobentries, mergeBlobentries!, deleteBlobentries! # export addVariableBlobentry!, getVariableBlobentry, mergeVariableBlobentry!, deleteVariableBlobentry! # export addVariableBlobentries!, getVariableBlobentries, mergeVariableBlobentries!, deleteVariableBlobentries! # export addGraphBlobentry!, getGraphBlobentry, mergeGraphBlobentry!, deleteGraphBlobentry! # export addGraphBlobentries!, getGraphBlobentries, mergeGraphBlobentries!, deleteGraphBlobentries! # export addAgentBlobentry!, getAgentBlobentry, mergeAgentBlobentry!, deleteAgentBlobentry! # export addAgentBlobentries!, getAgentBlobentries, mergeAgentBlobentries!, deleteAgentBlobentries! -#TODO blob entries not implemented on factors yet # export addFactorBlobentry!, getFactorBlobentry, mergeFactorBlobentry!, deleteFactorBlobentry! # export addFactorBlobentries!, getFactorBlobentries, mergeFactorBlobentries!, deleteFactorBlobentries! -# TODO first pass progress # export addVariableBloblet!, getVariableBloblet, mergeVariableBloblet!, deleteVariableBloblet! # export addVariableBloblets!, getVariableBloblets, mergeVariableBloblets!, deleteVariableBloblets! # export addFactorBloblet!, getFactorBloblet, mergeFactorBloblet!, deleteFactorBloblet! @@ -246,13 +257,45 @@ export GraphsDFG # export addGraphBloblets!, getGraphBloblets, mergeGraphBloblets!, deleteGraphBloblets! ## list -# export listVariables, listFactors, listStates, listBlobentries, listFactorBlobEntries, listGraphBlobentries, listAgentBlobentries -# not implemented yet (maybe not for DFG v1.0 yet): -# export listVariableMetadata, listFactorMetadata, listAgentMetadata, listGraphMetadata -# export listVariableBlobentryMetadata, listFactorBlobentryMetadata, listAgentBlobentryMetadata, listGraphBlobentryMetadata +# export listVariables, listFactors, listStates, listVariableBlobentries, listFactorBlobEntries, listGraphBlobentries, listAgentBlobentries +# export listVariableBloblets, listFactorBloblets, listAgentBloblets, listGraphBloblets + +# tags +# export listVariableTags, mergeVariableTags!, deleteVariableTags! +# export listFactorTags, mergeFactorTags!, deleteFactorTags! +# export listGraphTags, mergeGraphTags!, deleteGraphTags! +# export listAgentTags, mergeAgentTags!, deleteAgentTags! + +# has +# export hasVariable, hasFactor, hasState +# export hasVariableBlobentry, hasFactorBlobentry, hasGraphBlobentry, hasAgentBlobentry +# export hasVariableBloblet, hasFactorBloblet, hasGraphBloblet, hasAgentBloblet +# export hasVariableTags, hasFactorTags, hasGraphTags, hasAgentTags export deleteVariables! export deleteFactors! + +# Tags +export listVariableTags +export mergeVariableTags! +export deleteVariableTags! +export hasVariableTags + +export listFactorTags +export mergeFactorTags! +export deleteFactorTags! +export hasFactorTags + +export listGraphTags +export mergeGraphTags! +export deleteGraphTags! +export hasGraphTags + +export listAgentTags +export mergeAgentTags! +export deleteAgentTags! +export hasAgentTags + ##============================================================================== ## Common Accessors ##============================================================================== @@ -275,16 +318,6 @@ public FolderStore ##------------------------------------------------------------------------------ # tags is a set: get/list, merge, empty, and remove (we don't have add but merge) -export listVariableTags -export listFactorTags -export listGraphTags -export listAgentTags - -export mergeVariableTags! -export mergeFactorTags! -export mergeGraphTags! -export mergeAgentTags! - public listTags public mergeTags! public emptyTags! @@ -302,17 +335,44 @@ export mergeVariableBloblet! export deleteVariableBloblet! export listVariableBloblets +export addVariableBloblets! +export getVariableBloblets +export mergeVariableBloblets! +export deleteVariableBloblets! + export getAgentBloblet export addAgentBloblet! export mergeAgentBloblet! export deleteAgentBloblet! export listAgentBloblets +export addAgentBloblets! +export getAgentBloblets +export mergeAgentBloblets! +export deleteAgentBloblets! + export getGraphBloblet export addGraphBloblet! export mergeGraphBloblet! export deleteGraphBloblet! export listGraphBloblets + +export addGraphBloblets! +export getGraphBloblets +export mergeGraphBloblets! +export deleteGraphBloblets! + +export addFactorBloblet! +export getFactorBloblet +export mergeFactorBloblet! +export deleteFactorBloblet! +export listFactorBloblets + +export addFactorBloblets! +export getFactorBloblets +export mergeFactorBloblets! +export deleteFactorBloblets! + ##------------------------------------------------------------------------------ ## FileDFG ##------------------------------------------------------------------------------ @@ -333,9 +393,6 @@ export lsf # alias for listFactors ## Other utility functions ##------------------------------------------------------------------------------ -export listNeighborhood -export listNeighbors - ## TODO maybe move to DFG from SDK # addAgent! # deleteAgent! @@ -360,7 +417,8 @@ public getStateKind # list of unstable functions not exported any more # will move to public or deprecate over time const unstable_functions::Vector{Symbol} = [ - :getTags, + :listNeighborhood, + :listNeighbors, :InMemoryBlobstore, :exists, :compare, @@ -440,12 +498,17 @@ const unstable_functions::Vector{Symbol} = [ :setSolverParams!, :setDescription!, :setSolvable!, - :setTags!, :setSolvedCount!, :setMarginalized!, # no set on these #deprecated in v0.29 + :setTags!, + :VariableCompute, + :AbstractPackedBelief, + :PackedBelief, + :AbstractPackedObservation, + :PackedObservation, :updateMetadata!,## TODO deprecated or obsolete :updateBlob!,## TODO deprecated or obsolete :getFactorState, # FIXME getFactorState were questioned and being reviewed again for name, other than that they are checked. @@ -601,7 +664,6 @@ const LocalDFG = GraphsDFG include("services/Tags.jl") include("services/Bloblet.jl") -include("services/Blobentry.jl") # Common includes include("services/DFGVariable.jl") diff --git a/src/FileDFG/services/FileDFG.jl b/src/FileDFG/services/FileDFG.jl index 9bbc7908..a24c826d 100644 --- a/src/FileDFG/services/FileDFG.jl +++ b/src/FileDFG/services/FileDFG.jl @@ -118,7 +118,7 @@ function loadDFG!( # extract the factor graph from fileDFG folder variablefiles = readdir(joinpath(loaddir, "variables"); sort = false, join = true) - # type instability on `variables` as either `::Vector{Variable}` or `::Vector{VariableCompute{<:}}` (vector of abstract) + # type instability on `variables` as either `::Vector{Variable}` or `::Vector{VariableDFG{<:}}` (vector of abstract) variables = @showprogress dt=1 desc = "loading variables" asyncmap( variablefiles, ) do file diff --git a/src/GraphsDFG/FactorGraphs/FactorGraphs.jl b/src/GraphsDFG/FactorGraphs/FactorGraphs.jl index 567de3dc..11740fc7 100644 --- a/src/GraphsDFG/FactorGraphs/FactorGraphs.jl +++ b/src/GraphsDFG/FactorGraphs/FactorGraphs.jl @@ -95,8 +95,7 @@ has_vertex(g::FactorGraph, x...) = has_vertex(g.graph, x...) inneighbors(g::FactorGraph, v::Integer) = inneighbors(g.graph, v) outneighbors(g::FactorGraph, v::Integer) = fadj(g.graph, v) -is_directed(::Type{FactorGraph}) = false -is_directed(::Type{FactorGraph{T, V, F}}) where {T, V, F} = false +is_directed(::Type{<:FactorGraph}) = false is_directed(g::FactorGraph) = false Base.zero(g::FactorGraph{T, V, F}) where {T, V, F} = FactorGraph{T, V, F}(0, 0) diff --git a/src/GraphsDFG/entities/GraphsDFG.jl b/src/GraphsDFG/entities/GraphsDFG.jl index 492d99cf..b1831a0e 100644 --- a/src/GraphsDFG/entities/GraphsDFG.jl +++ b/src/GraphsDFG/entities/GraphsDFG.jl @@ -82,26 +82,18 @@ function GraphsDFG{T, V, F}( return GraphsDFG{T, V, F}(g, solverParams, blobStores, graph, agent) end -# GraphsDFG{T}(; kwargs...) where T <: AbstractDFGParams = GraphsDFG{T,VariableCompute,FactorDFG}(;kwargs...) +# GraphsDFG{T}(; kwargs...) where T <: AbstractDFGParams = GraphsDFG{T,VariableDFG,FactorDFG}(;kwargs...) function GraphsDFG{T}( - g::FactorGraph{Int, VariableCompute, FactorDFG} = FactorGraph{ - Int, - VariableCompute, - FactorDFG, - }(); + g::FactorGraph{Int, VariableDFG, FactorDFG} = FactorGraph{Int, VariableDFG, FactorDFG}(); kwargs..., ) where {T <: AbstractDFGParams} - return GraphsDFG{T, VariableCompute, FactorDFG}(g; kwargs...) + return GraphsDFG{T, VariableDFG, FactorDFG}(g; kwargs...) end function GraphsDFG( - g::FactorGraph{Int, VariableCompute, FactorDFG} = FactorGraph{ - Int, - VariableCompute, - FactorDFG, - }(); + g::FactorGraph{Int, VariableDFG, FactorDFG} = FactorGraph{Int, VariableDFG, FactorDFG}(); solverParams::T = NoSolverParams(), kwargs..., ) where {T} - return GraphsDFG{T, VariableCompute, FactorDFG}(g; solverParams, kwargs...) + return GraphsDFG{T, VariableDFG, FactorDFG}(g; solverParams, kwargs...) end diff --git a/src/GraphsDFG/services/GraphsDFG.jl b/src/GraphsDFG/services/GraphsDFG.jl index 55983c75..86992d48 100644 --- a/src/GraphsDFG/services/GraphsDFG.jl +++ b/src/GraphsDFG/services/GraphsDFG.jl @@ -91,11 +91,6 @@ function mergeVariable!(dfg::GraphsDFG, variable::AbstractGraphVariable) return 1 end -function DFG.mergeVariables!(dfg::GraphsDFG, variables) - cnts = map(v -> mergeVariable!(dfg, v), variables) - return sum(cnts) -end - function mergeFactor!(dfg::GraphsDFG, factor::AbstractGraphFactor) if !haskey(dfg.g.factors, factor.label) addFactor!(dfg, factor) @@ -112,11 +107,6 @@ function mergeFactor!(dfg::GraphsDFG, factor::AbstractGraphFactor) return 1 end -function DFG.mergeFactors!(dfg::GraphsDFG, factors) - cnts = map(f -> mergeFactor!(dfg, f), factors) - return sum(cnts) -end - function deleteVariable!(dfg::GraphsDFG, label::Symbol)#::Tuple{AbstractGraphVariable, Vector{<:AbstractGraphFactor}} if !haskey(dfg.g.variables, label) throw(LabelNotFoundError("Variable", label)) @@ -314,14 +304,6 @@ function isConnected(dfg::GraphsDFG) # return length(Graphs.connected_components(dfg.g)) == 1 end -_isSolvable(dfg::GraphsDFG, label::Symbol, ready::Nothing) = true - -function _isSolvable(dfg::GraphsDFG, label::Symbol, ready::Int) - haskey(dfg.g.variables, label) && (return dfg.g.variables[label].solvable[] >= ready) - haskey(dfg.g.factors, label) && (return dfg.g.factors[label].solvable[] >= ready) - throw(LabelNotFoundError(label)) -end - function listNeighbors( dfg::GraphsDFG, node::AbstractGraphNode; @@ -653,6 +635,42 @@ function DFG.mergeAgentBlobentries!(dfg::GraphsDFG, entries::Vector{Blobentry}) return sum(cnts) end +##============================================================================= +## Variable Blobentries +##============================================================================= + +function DFG.addVariableBlobentry!(dfg::GraphsDFG, label::Symbol, entry::Blobentry) + variable = getVariable(dfg, label) + addBlobentry!(variable, entry) + return entry +end + +function DFG.mergeVariableBlobentry!(dfg::GraphsDFG, label::Symbol, entry::Blobentry) + return mergeBlobentry!(getVariable(dfg, label), entry) +end + +function DFG.deleteVariableBlobentry!(dfg::GraphsDFG, label::Symbol, entryLabel::Symbol) + return deleteBlobentry!(getVariable(dfg, label), entryLabel) +end + +##============================================================================= +## Factor Blobentries +##============================================================================= + +function DFG.addFactorBlobentry!(dfg::GraphsDFG, label::Symbol, entry::Blobentry) + factor = getFactor(dfg, label) + addBlobentry!(factor, entry) + return entry +end + +function DFG.mergeFactorBlobentry!(dfg::GraphsDFG, label::Symbol, entry::Blobentry) + return mergeBlobentry!(getFactor(dfg, label), entry) +end + +function DFG.deleteFactorBlobentry!(dfg::GraphsDFG, label::Symbol, entryLabel::Symbol) + return deleteBlobentry!(getFactor(dfg, label), entryLabel) +end + function DFG.deleteGraphBlobentry!(dfg::GraphsDFG, label::Symbol) if !haskey(dfg.graph.blobentries, label) throw(LabelNotFoundError("Blobentry", label)) diff --git a/src/entities/DFGVariable.jl b/src/entities/DFGVariable.jl index 3d2ff682..ac0f8280 100644 --- a/src/entities/DFGVariable.jl +++ b/src/entities/DFGVariable.jl @@ -327,7 +327,7 @@ end ## Conversion constructors ##============================================================================== -function VariableSummary(v::VariableCompute{T}) where {T} +function VariableSummary(v::VariableDFG{T}) where {T} return VariableSummary( v.label, v.timestamp, diff --git a/src/services/AbstractDFG.jl b/src/services/AbstractDFG.jl index e57791f0..45bc3c39 100644 --- a/src/services/AbstractDFG.jl +++ b/src/services/AbstractDFG.jl @@ -144,14 +144,14 @@ function hasFactor end """ $(SIGNATURES) -Add a VariableCompute to a DFG. +Add a VariableDFG to a DFG. Implement `addVariable!(dfg::AbstractDFG, variable::AbstractGraphVariable)` """ function addVariable! end """ $(SIGNATURES) -Add a Vector{VariableCompute} to a DFG. +Add a Vector{VariableDFG} to a DFG. Implement `addVariables!(dfg::AbstractDFG, variables::Vector{<:AbstractGraphVariable})` """ function addVariables!(dfg::AbstractDFG, variables::Vector{<:AbstractGraphVariable}) @@ -179,7 +179,7 @@ end """ $(SIGNATURES) -Get a VariableCompute from a DFG using its label. +Get a VariableDFG from a DFG using its label. Implement `getVariable(dfg::AbstractDFG, label::Symbol)` """ function getVariable end @@ -238,7 +238,11 @@ otherwise, the variable will be added to the graph. Implement `mergeVariable!(dfg::AbstractDFG, variable::AbstractGraphVariable)` """ function mergeVariable! end -function mergeVariables! end + +function mergeVariables!(dfg::AbstractDFG, variables::Vector{<:AbstractGraphVariable}) + counts = asyncmap(v->mergeVariable!(dfg, v), variables) + return sum(counts) +end """ $(SIGNATURES) @@ -247,11 +251,15 @@ otherwise, the factor will be added to the graph. Implement `mergeFactor!(dfg::AbstractDFG, factor::AbstractGraphFactor)` """ function mergeFactor! end -function mergeFactors! end + +function mergeFactors!(dfg::AbstractDFG, factors::Vector{<:AbstractGraphFactor}) + counts = asyncmap(f->mergeFactor!(dfg, f), factors) + return sum(counts) +end """ $(SIGNATURES) -Delete a VariableCompute from the DFG. +Delete a VariableDFG from the DFG. Implement `deleteVariable!(dfg::AbstractDFG, label::Symbol)` """ function deleteVariable! end @@ -307,7 +315,7 @@ end Return whether `sym::Symbol` represents a variable vertex in the graph DFG. Checks whether it both exists in the graph and is a variable. -(If you rather want a quick for type, just do node isa VariableCompute) +(If you rather want a quick for type, just do node isa VariableDFG) Implement `isVariable(dfg::AbstractDFG, label::Symbol)` """ function isVariable end @@ -350,7 +358,7 @@ function listNeighbors end #TODO should this signiture be standardized or removed? """ $(SIGNATURES) -Get a VariableCompute with a specific solver key. +Get a VariableDFG with a specific solver key. In memory types still return a reference, other types returns a variable with only solveKey. """ function getVariable(dfg::AbstractDFG, label::Symbol, solveKey::Symbol) @@ -436,7 +444,7 @@ Common function for copying nodes from one graph into another graph. This is overridden in specialized implementations for performance. Orphaned factors are not added, with a warning if verbose. Set `overwriteDest` to overwrite existing variables and factors in the destination DFG. -NOTE: copyGraphMetadata not supported yet. +NOTE: `copyGraphMetadata` is deprecated – use agent/graph Bloblets instead. Related: - [`deepcopyGraph`](@ref) - [`deepcopyGraph!`](@ref) @@ -498,8 +506,10 @@ function copyGraph!( end if copyGraphMetadata - setAgentMetadata(destDFG, getAgentMetadata(sourceDFG)) - setGraphMetadata(destDFG, getGraphMetadata(sourceDFG)) + error( + "copyGraphMetadata keyword has been removed – metadata APIs were replaced by Bloblets. " * + "Copy agent/graph Bloblets manually before calling copyGraph!", + ) end return nothing end diff --git a/src/services/Blobentry.jl b/src/services/Blobentry.jl deleted file mode 100644 index 3a5dde67..00000000 --- a/src/services/Blobentry.jl +++ /dev/null @@ -1,15 +0,0 @@ -function getVariableBlobentry(dfg::InMemoryDFGTypes, varLabel::Symbol, label::Symbol) - return getBlobentry(getVariable(dfg, varLabel), label) -end - -function addVariableBlobentry!(dfg::InMemoryDFGTypes, vLbl::Symbol, entry::Blobentry) - return addBlobentry!(getVariable(dfg, vLbl), entry) -end - -function mergeVariableBlobentry!(dfg::InMemoryDFGTypes, label::Symbol, bde::Blobentry) - return mergeBlobentry!(getVariable(dfg, label), bde) -end - -function deleteVariableBlobentry!(dfg::InMemoryDFGTypes, label::Symbol, key::Symbol) - return deleteBlobentry!(getVariable(dfg, label), key) -end diff --git a/src/services/CompareUtils.jl b/src/services/CompareUtils.jl index 169320a5..adfaf1d0 100644 --- a/src/services/CompareUtils.jl +++ b/src/services/CompareUtils.jl @@ -246,8 +246,8 @@ end Compare that all fields are the same in a `::FactorGraph` variable. """ function compareVariable( - A::VariableCompute, - B::VariableCompute; + A::VariableDFG, + B::VariableDFG; skip::Vector{Symbol} = Symbol[], show::Bool = true, skipsamples::Bool = true, diff --git a/src/services/CustomPrinting.jl b/src/services/CustomPrinting.jl index ae0ceb2e..691520d8 100644 --- a/src/services/CustomPrinting.jl +++ b/src/services/CustomPrinting.jl @@ -2,11 +2,11 @@ ## Printing Variables and Factors ##============================================================================== -printVariable(vert::VariableCompute; kwargs...) = printVariable(stdout::IO, vert; kwargs...) +printVariable(vert::VariableDFG; kwargs...) = printVariable(stdout::IO, vert; kwargs...) function printVariable( io::IO, - vert::VariableCompute; + vert::VariableDFG; short::Bool = false, compact::Bool = true, limit::Bool = true, @@ -175,7 +175,7 @@ end ## Overloading show ##============================================================================== # Base.show_default(io, v) -function Base.show(io::IO, ::MIME"text/plain", v::VariableCompute) +function Base.show(io::IO, ::MIME"text/plain", v::VariableDFG) return printVariable(io, v; short = true, limit = false) end diff --git a/src/services/DFGFactor.jl b/src/services/DFGFactor.jl index 61a99a9f..ff43d134 100644 --- a/src/services/DFGFactor.jl +++ b/src/services/DFGFactor.jl @@ -141,8 +141,6 @@ getManifold(f::AbstractGraphFactor) = getManifold(getObservation(f)) ##------------------------------------------------------------------------------ ## COMMON -# getTags -# setTags! ##------------------------------------------------------------------------------ ## timestamp diff --git a/src/services/DFGVariable.jl b/src/services/DFGVariable.jl index c1d21acc..9f516d0d 100644 --- a/src/services/DFGVariable.jl +++ b/src/services/DFGVariable.jl @@ -14,7 +14,7 @@ Get the kind of the variable's state, eg. `Pose2`, `Point3`, etc. as an instance of `StateType`. """ -getStateKind(::VariableCompute{T}) where {T} = T() +getStateKind(::VariableDFG{T}) where {T} = T() getStateKind(::State{T}) where {T} = T() @@ -116,7 +116,7 @@ end Interface function to return the `<:ManifoldsBase.AbstractManifold` object of `variableType<:StateType`. """ getManifold(::T) where {T <: StateType} = getManifold(T) -getManifold(vari::VariableCompute) = getStateKind(vari) |> getManifold +getManifold(vari::VariableDFG) = getStateKind(vari) |> getManifold getManifold(state::State) = getStateKind(state) |> getManifold # covers both <:StateType and <:AbstractObservation getManifold(dfg::AbstractDFG, lbl::Symbol) = getManifold(dfg[lbl]) @@ -131,7 +131,7 @@ getDimension(::Type{T}) where {T <: StateType} = manifold_dimension(getManifold( getDimension(::T) where {T <: StateType} = manifold_dimension(getManifold(T)) getDimension(M::ManifoldsBase.AbstractManifold) = manifold_dimension(M) getDimension(p::Distributions.Distribution) = length(p) -getDimension(var::VariableCompute) = getDimension(getStateKind(var)) +getDimension(var::VariableDFG) = getDimension(getStateKind(var)) """ $SIGNATURES @@ -213,7 +213,7 @@ Related isSolved, setSolvedCount! """ getSolvedCount(v::State) = v.solves -function getSolvedCount(v::VariableCompute, solveKey::Symbol = :default) +function getSolvedCount(v::VariableDFG, solveKey::Symbol = :default) return getState(v, solveKey) |> getSolvedCount end function getSolvedCount(dfg::AbstractDFG, sym::Symbol, solveKey::Symbol = :default) @@ -230,7 +230,7 @@ Related getSolved, isSolved """ setSolvedCount!(v::State, val::Int) = v.solves = val -function setSolvedCount!(v::VariableCompute, val::Int, solveKey::Symbol = :default) +function setSolvedCount!(v::VariableDFG, val::Int, solveKey::Symbol = :default) return setSolvedCount!(getState(v, solveKey), val) end function setSolvedCount!( @@ -252,7 +252,7 @@ Related getSolved, setSolved! """ isSolved(v::State) = 0 < v.solves -function isSolved(v::VariableCompute, solveKey::Symbol = :default) +function isSolved(v::VariableDFG, solveKey::Symbol = :default) return getState(v, solveKey) |> isSolved end function isSolved(dfg::AbstractDFG, sym::Symbol, solveKey::Symbol = :default) @@ -270,7 +270,7 @@ Returns state of variable data `.initialized` flag. Notes: - used by both factor graph variable and Bayes tree clique logic. """ -function isInitialized(var::VariableCompute, key::Symbol = :default) +function isInitialized(var::VariableDFG, key::Symbol = :default) return getState(var, key).initialized end @@ -286,7 +286,7 @@ Return `::Bool` on whether this variable has been marginalized. Notes: - State default `solveKey=:default` """ -function isMarginalized(vert::VariableCompute, solveKey::Symbol = :default) +function isMarginalized(vert::VariableDFG, solveKey::Symbol = :default) return getState(vert, solveKey).marginalized end function isMarginalized(dfg::AbstractDFG, sym::Symbol, solveKey::Symbol = :default) @@ -301,7 +301,7 @@ Mark a variable as marginalized `true` or `false`. function setMarginalized!(vnd::State, val::Bool) return vnd.marginalized = val end -function setMarginalized!(vari::VariableCompute, val::Bool, solveKey::Symbol = :default) +function setMarginalized!(vari::VariableDFG, val::Bool, solveKey::Symbol = :default) return setMarginalized!(getState(vari, solveKey), val) end function setMarginalized!( @@ -321,7 +321,7 @@ end # |---------------------|:-----:|:----:|:---------:|:----------------:|:--------:|:----------:|:---------:|:-----------:| # | VariableSkeleton | X | X | | | | | | | # | VariableSummary | X | X | X | X | | | | X | -# | VariableCompute | X | X | x | | X | X | X | X | +# | VariableDFG | X | X | x | | X | X | X | X | # ##------------------------------------------------------------------------------ @@ -337,8 +337,6 @@ end ##------------------------------------------------------------------------------ ## COMMON -# getTags -# setTags! ##------------------------------------------------------------------------------ ## timestamp @@ -384,9 +382,9 @@ end ##------------------------------------------------------------------------------ ## CRUD: get, add, update, delete ##------------------------------------------------------------------------------ -hasState(v::VariableCompute, label::Symbol) = haskey(v.states, label) +hasState(v::VariableDFG, label::Symbol) = haskey(v.states, label) -function getState(v::VariableCompute, label::Symbol) +function getState(v::VariableDFG, label::Symbol) !haskey(refStates(v), label) && throw(LabelNotFoundError("State", label)) return refStates(v)[label] end @@ -414,7 +412,7 @@ function addState!(dfg::GraphsDFG, variableLabel::Symbol, state::State) return addState!(var, state) end -function addState!(v::VariableCompute, state::State) +function addState!(v::VariableDFG, state::State) if haskey(refStates(v), state.label) throw(LabelExistsError("State", state.label)) end @@ -453,7 +451,7 @@ function mergeState!(dfg::GraphsDFG, variableLabel::Symbol, vnd::State) return mergeState!(getVariable(dfg, variableLabel), vnd) end -function mergeState!(v::VariableCompute, vnd::State) +function mergeState!(v::VariableDFG, vnd::State) if !haskey(v.states, vnd.label) addState!(v, vnd) else @@ -497,7 +495,7 @@ function deleteState!(dfg::GraphsDFG, variableLabel::Symbol, label::Symbol) return deleteState!(getVariable(dfg, variableLabel), label) end -function deleteState!(v::VariableCompute, label::Symbol) +function deleteState!(v::VariableDFG, label::Symbol) if !haskey(v.states, label) throw(LabelNotFoundError("State", label)) end @@ -505,7 +503,7 @@ function deleteState!(v::VariableCompute, label::Symbol) return 1 end -function deleteState!(dfg::AbstractDFG, sourceVariable::VariableCompute, label::Symbol) +function deleteState!(dfg::AbstractDFG, sourceVariable::VariableDFG, label::Symbol) return deleteState!(dfg, sourceVariable.label, label) end @@ -538,7 +536,7 @@ end $(SIGNATURES) List all the variable state labels. """ -function listStates(v::VariableCompute; labelFilter::Union{Nothing, Function} = nothing) +function listStates(v::VariableDFG; labelFilter::Union{Nothing, Function} = nothing) labels = collect(keys(v.states)) return filterDFG!(labels, labelFilter) end diff --git a/src/services/Tags.jl b/src/services/Tags.jl index 202c510d..dd92fe34 100644 --- a/src/services/Tags.jl +++ b/src/services/Tags.jl @@ -1,20 +1,8 @@ # from CommonAccessors.jl -##------------------------------------------------------------------------------ -## tags -##------------------------------------------------------------------------------ -""" -$SIGNATURES - -Set the tags for a Node. -""" -function setTags!(node, tags::Union{Vector{Symbol}, Set{Symbol}}) - node.tags !== tags && empty!(node.tags) - return union!(node.tags, tags) -end - ##============================================================================== -## TAGS as a set, list, merge, remove, empty +## TAGS as a set -- list, merge, delete, (empty?) ##============================================================================== +# Node level functions (in-memory) """ $SIGNATURES """ @@ -46,15 +34,14 @@ Empty all tags from the node (empty) """ emptyTags!(node) = empty!(refTags(node)) +# DFG level functions +##============================================================================== + """ $SIGNATURES -Return the tags for a variable or factor. +List the tags for a variable. """ - -#alias for completeness #TODO keep or remove getTags? -const getTags = refTags - function listVariableTags(dfg::AbstractDFG, sym::Symbol) return listTags(getVariable(dfg, sym)) end @@ -103,11 +90,49 @@ function mergeAgentTags!(dfg::InMemoryDFGTypes, tags) return length(tags) end +##------------------------------------------------------------------------------ + +function deleteVariableTags!(dfg::InMemoryDFGTypes, label::Symbol, tags) + return deleteTags!(getVariable(dfg, label), tags) +end + +function deleteFactorTags!(dfg::InMemoryDFGTypes, label::Symbol, tags) + return deleteTags!(getFactor(dfg, label), tags) +end + +function deleteGraphTags!(dfg::InMemoryDFGTypes, tags) + deleteTags!(dfg.graph, tags) + return length(tags) +end + +function deleteAgentTags!(dfg::InMemoryDFGTypes, tags) + deleteTags!(dfg.agent, tags) + return length(tags) +end + +##------------------------------------------------------------------------------ + +function hasVariableTags(dfg::AbstractDFG, sym::Symbol, tags::Vector{Symbol}) + return tags ⊆ listVariableTags(dfg, sym) +end + +function hasFactorTags(dfg::AbstractDFG, sym::Symbol, tags::Vector{Symbol}) + return tags ⊆ listFactorTags(dfg, sym) +end + +function hasGraphTags(dfg::AbstractDFG, tags::Vector{Symbol}) + return tags ⊆ listGraphTags(dfg) +end + +function hasAgentTags(dfg::AbstractDFG, tags::Vector{Symbol}) + return tags ⊆ listAgentTags(dfg) +end + ## function listTags(dfg::AbstractDFG, sym::Symbol) getFnc = isVariable(dfg, sym) ? getVariable : getFactor - return refTags(getFnc(dfg, sym)) + return listTags(getFnc(dfg, sym)) end function mergeTags!(dfg::InMemoryDFGTypes, sym::Symbol, tags) @@ -131,10 +156,8 @@ end """ $SIGNATURES -Determine if the variable or factor neighbors have the `tags:;Vector{Symbol}`, and `matchAll::Bool`. +Determine if the variable or factor neighbors have the `tags::Vector{Symbol}``. """ -function hasTags(dfg::AbstractDFG, sym::Symbol, tags::Vector{Symbol}; matchAll::Bool = true) - # - alltags = listTags(dfg, sym) - return length(alltags ∩ tags) >= (matchAll ? length(tags) : 1) +function hasTags(dfg::AbstractDFG, sym::Symbol, tags::Vector{Symbol}) + return tags ⊆ listTags(dfg, sym) end diff --git a/test/GraphsDFGSummaryTypes.jl b/test/GraphsDFGSummaryTypes.jl index 388caa24..f4c7efcc 100644 --- a/test/GraphsDFGSummaryTypes.jl +++ b/test/GraphsDFGSummaryTypes.jl @@ -9,7 +9,7 @@ function DistributedFactorGraphs.VariableSummary(label::Symbol) TimeDateZone("2025-11-13T15:21:57.474125421+01:00"), Set{Symbol}(), :Pose2, - Dict{Symbol, Blobentry}(), + DFG.Blobentries(), ) end @@ -19,7 +19,7 @@ function DistributedFactorGraphs.VariableSummary(label::Symbol, ::State{T}) wher TimeDateZone("2025-11-13T15:21:57.474125421+01:00"), Set{Symbol}(), Symbol(T), - Dict{Symbol, Blobentry}(), + DFG.Blobentries(), ) end @@ -93,10 +93,10 @@ end global dfg, v1, v2, f1 @test getLabel(v1) == v1.label - @test getTags(v1) == v1.tags + @test DFG.refTags(v1) === v1.tags @test getLabel(f1) == f1.label - @test getTags(f1) == f1.tags + @test DFG.refTags(f1) === f1.tags if VARTYPE == VariableSummary @test getTimestamp(v1) == v1.timestamp diff --git a/test/compareTests.jl b/test/compareTests.jl index bebbfc5b..165f405e 100644 --- a/test/compareTests.jl +++ b/test/compareTests.jl @@ -20,18 +20,16 @@ vnd2.val[1] = [0.1;] @test !(vnd1 == vnd2) @test !(vnd1 == vnd3) -# VariableCompute -v1 = VariableCompute(:x1, TestVariableType1()) +# VariableDFG +v1 = VariableDFG(:x1, TestVariableType1()) v2 = deepcopy(v1) -v3 = VariableCompute(:x2, TestVariableType2()) +v3 = VariableDFG(:x2, TestVariableType2()) @test v1 == v2 setSolvable!(v2, 0) @test !(v1 == v2) @test !(v1 == v3) -@test !( - VariableCompute(:x1, TestVariableType1()) == VariableCompute(:x1, TestVariableType2()) -) +@test !(VariableDFG(:x1, TestVariableType1()) == VariableDFG(:x1, TestVariableType2())) facstate1 = DFG.Recipestate(; eliminated = true, potentialused = true) facstate2 = deepcopy(facstate1) diff --git a/test/iifInterfaceTests.jl b/test/iifInterfaceTests.jl index dd5de0a8..d70a5221 100644 --- a/test/iifInterfaceTests.jl +++ b/test/iifInterfaceTests.jl @@ -153,6 +153,7 @@ end @test issetequal(ls(dfg, Position{1}), [:a, :b]) varNearTs = findVariableNearTimestamp(dfg, now()) + # TODO @test_skip varNearTs[1][1] == [:b] end @@ -174,7 +175,7 @@ end # Accessors @test getLabel(v1) == v1.label - @test getTags(v1) == v1.tags + @test DFG.refTags(v1) === v1.tags @test getTimestamp(v1) == v1.timestamp @test getState(v1, :default) === v1.states[:default] @test refStates(v1) == v1.states @@ -184,7 +185,7 @@ end @test typeof(getStateKind(v1)) == Position{1} @test getLabel(f1) == f1.label - @test getTags(f1) == f1.tags + @test DFG.refTags(f1) === f1.tags @test DFG.getRecipestate(f1) === f1.state @test getObservation(f1) === f1.observation @@ -197,14 +198,13 @@ end @test_throws LabelNotFoundError isInitialized(v2, :second) - # Session, robot, and user small data tests - #FIXME change to Bloblets - # smallRobotData = Dict{Symbol, MetadataTypes}(:a => "43", :b => "Hello") - # smallSessionData = Dict{Symbol, MetadataTypes}(:a => "44", :b => "Hello") - # setAgentMetadata!(dfg, deepcopy(smallRobotData)) - # setGraphMetadata!(dfg, deepcopy(smallSessionData)) - # @test getAgentMetadata(dfg) == smallRobotData - # @test getGraphMetadata(dfg) == smallSessionData + # Graph and Agent small data tests + agentBloblets = [Bloblet(:a, "43"), Bloblet(:b, "Hello")] + graphBloblets = [Bloblet(:c, "44"), Bloblet(:d, "Hello")] + DFG.addAgentBloblets!(dfg, agentBloblets) + DFG.addGraphBloblets!(dfg, graphBloblets) + @test DFG.listAgentBloblets(dfg) == [:a, :b] + @test DFG.listGraphBloblets(dfg) == [:c, :d] end @testset "Data Entries" begin diff --git a/test/interfaceTests.jl b/test/interfaceTests.jl index 3bd8630a..0d77b6c2 100644 --- a/test/interfaceTests.jl +++ b/test/interfaceTests.jl @@ -7,6 +7,7 @@ if false using UUIDs using TimeZones using TimesDates + using DistributedFactorGraphs: OrderedDict include("testBlocks.jl") @@ -33,15 +34,15 @@ end end # User, Robot, Session Data -# @testset "User, Robot, Session Data" begin -# GraphAgentMetadata!(fg1) -# end +@testset "User, Robot, Session Data" begin + GraphAgentBloblets!(fg1) +end -# @testset "User, Robot, Session Blob Entries" begin -# GraphAgentBlobentries!(fg1) -# end +@testset "User, Robot, Session Blob Entries" begin + GraphAgentBlobentries!(fg1) +end -# VariableCompute structure construction and accessors +# VariableDFG structure construction and accessors @testset "DFG Variable" begin global var1, var2, var3, v1_tags, vorphan var1, var2, var3, vorphan, v1_tags = DFGVariableSCA() @@ -76,7 +77,7 @@ end @test occursin(r"timestamp", varstr) @test occursin(r"label", varstr) @test occursin(r"bandwidths", varstr) - # == "VariableCompute{TestVariableType1}\nlabel: a\ntags: Set([:VARIABLE, :POSE])\nsize marginal samples: (1, 1)\nkde bandwidths: [0.0]\nNo PPEs\n" + # == "VariableDFG{TestVariableType1}\nlabel: a\ntags: Set([:VARIABLE, :POSE])\nsize marginal samples: (1, 1)\nkde bandwidths: [0.0]\nNo PPEs\n" @test printFactor(iobuf, fac1; skipfields = [:timestamp]) === nothing @test occursin(r"FactorDFG.*\nlabel:\n:abf1", String(take!(iobuf))) diff --git a/test/plottingTest.jl b/test/plottingTest.jl index 6eaa3051..894c6493 100644 --- a/test/plottingTest.jl +++ b/test/plottingTest.jl @@ -11,7 +11,7 @@ using LieGroups # Now make a complex graph for connectivity tests numNodes = 10 dfg = GraphsDFG{NoSolverParams}() -verts = map(n -> VariableCompute(Symbol("x$n"), TestInferenceVariable1()), 1:numNodes) +verts = map(n -> VariableDFG(Symbol("x$n"), TestInferenceVariable1()), 1:numNodes) map(v -> addVariable!(dfg, v), verts) map( n -> addFactor!( diff --git a/test/testBlocks.jl b/test/testBlocks.jl index b274b9f4..c47b78d8 100644 --- a/test/testBlocks.jl +++ b/test/testBlocks.jl @@ -120,21 +120,8 @@ function DFGStructureAndAccessors( @test getSolverParams(fg) == NoSolverParams() #FIXME test bloblets - # @test setAgentMetadata!(fg, rd) == rd - # @test setGraphMetadata!(fg, sd) == sd - # @test getAgentMetadata(fg) == rd - # @test getGraphMetadata(fg) == sd - - # smallUserData = Dict{Symbol, MetadataTypes}(:a => "42", :b => "Hello") - # smallRobotData = Dict{Symbol, MetadataTypes}(:a => "43", :b => "Hello") - # smallSessionData = Dict{Symbol, MetadataTypes}(:a => "44", :b => "Hello") - - #TODO CRUD vs set - # @test setAgentMetadata!(fg, deepcopy(smallRobotData)) == smallRobotData - # @test setGraphMetadata!(fg, deepcopy(smallSessionData)) == smallSessionData - - # @test getAgentMetadata(fg) == smallRobotData - # @test getGraphMetadata(fg) == smallSessionData + @test DFG.getAgentBloblet(fg, :rd) == rd[:rd] + @test DFG.getGraphBloblet(fg, :sd) == sd[:sd] # NOTE see note in AbstractDFG.jl setSolverParams! @test_throws Exception setSolverParams!(fg, GeenSolverParams()) == GeenSolverParams() @@ -153,31 +140,30 @@ function DFGStructureAndAccessors( end # User, Robot, Session Data -function GraphAgentMetadata!(fg::AbstractDFG) - # "User, Robot, Session Data" - - # Robot Data - @test getAgentMetadata(fg, :a) == "43" - #TODO - @test_broken addAgentMetadata! - @test DFG.updateAgentMetadata!(fg, :b => "2") == getAgentMetadata(fg) - @test DFG.deleteAgentMetadata!(fg, :b) == 1 - @test DFG.emptyAgentMetadata!(fg) == Dict{Symbol, String}() - - # SessionData - @test getGraphMetadata(fg, :a) == "44" - #TODO - @test_broken addGraphMetadata! - @test DFG.updateGraphMetadata!(fg, :b => "3") == getGraphMetadata(fg) - @test DFG.deleteGraphMetadata!(fg, :b) == 1 - @test DFG.emptyGraphMetadata!(fg) == Dict{Symbol, String}() - - # TODO Set-like if we want eg. list, merge, etc - # listAgentMetadata - # listGraphMetadata - # mergeAgentData - # mergeGraphData - +function GraphAgentBloblets!(fg::AbstractDFG) + # Agent-level bloblets + agent_blob = Bloblet(:agent_blob, "ready") + @test addAgentBloblet!(fg, agent_blob) == agent_blob + @test getAgentBloblet(fg, agent_blob.label) == agent_blob + updated_agent_blob = Bloblet(agent_blob.label, "updated") + @test mergeAgentBloblet!(fg, updated_agent_blob) == 1 + @test getAgentBloblet(fg, agent_blob.label) == updated_agent_blob + @test agent_blob.label in listAgentBloblets(fg) + @test deleteAgentBloblet!(fg, agent_blob.label) == 1 + @test_throws DFG.LabelNotFoundError getAgentBloblet(fg, agent_blob.label) + @test_throws DFG.LabelNotFoundError deleteAgentBloblet!(fg, agent_blob.label) + + # Graph-level bloblets + graph_blob = Bloblet(:graph_blob, "running") + @test addGraphBloblet!(fg, graph_blob) == graph_blob + @test getGraphBloblet(fg, graph_blob.label) == graph_blob + updated_graph_blob = Bloblet(graph_blob.label, "complete") + @test mergeGraphBloblet!(fg, updated_graph_blob) == 1 + @test getGraphBloblet(fg, graph_blob.label) == updated_graph_blob + @test graph_blob.label in listGraphBloblets(fg) + @test deleteGraphBloblet!(fg, graph_blob.label) == 1 + @test_throws DFG.LabelNotFoundError getGraphBloblet(fg, graph_blob.label) + @test_throws DFG.LabelNotFoundError deleteGraphBloblet!(fg, graph_blob.label) end # User, Robot, Session Data Blob Entries @@ -198,6 +184,10 @@ function GraphAgentBlobentries!(fg::AbstractDFG) @test hasAgentBlobentry(fg, :key1) == false @test_throws DFG.LabelNotFoundError getAgentBlobentry(fg, :key1) @test_throws DFG.LabelNotFoundError deleteAgentBlobentry!(fg, :key1) + @test addAgentBlobentries!(fg, [be]) == [be] + @test deleteAgentBlobentries!(fg, [:key1]) == 1 + @test mergeAgentBlobentries!(fg, [be]) == 1 + @test deleteAgentBlobentries!(fg, [:key1]) == 1 # Graph Blob Entries ae = addGraphBlobentry!(fg, be) @@ -213,6 +203,10 @@ function GraphAgentBlobentries!(fg::AbstractDFG) @test hasGraphBlobentry(fg, :key1) == false @test_throws DFG.LabelNotFoundError getGraphBlobentry(fg, :key1) @test_throws DFG.LabelNotFoundError deleteGraphBlobentry!(fg, :key1) + @test addGraphBlobentries!(fg, [be]) == [be] + @test deleteGraphBlobentries!(fg, [:key1]) == 1 + @test mergeGraphBlobentries!(fg, [be]) == 1 + @test deleteGraphBlobentries!(fg, [:key1]) == 1 be2 = Blobentry(; blobid = uuid4(), label = :key2, blobstore = :b) @@ -250,7 +244,7 @@ function DFGVariableSCA() v1_tags = Set([:VARIABLE, :POSE]) testTimestamp = now(localzone()) # Constructors - v1 = VariableCompute( + v1 = VariableDFG( v1_lbl, TestVariableType1(); tags = v1_tags, @@ -258,18 +252,18 @@ function DFGVariableSCA() states = OrderedDict(:default => State{TestVariableType1}(; label = :default)), bloblets = DFG.Bloblets(:small => DFG.Bloblet(:small, "data")), ) - v2 = VariableCompute( + v2 = VariableDFG( :b, State{TestVariableType2}(; label = :default); tags = Set([:VARIABLE, :LANDMARK]), ) - v3 = VariableCompute( + v3 = VariableDFG( :c, State{TestVariableType2}(; label = :default); timestamp = ZonedDateTime("2020-08-11T00:12:03.000-05:00"), ) - vorphan = VariableCompute( + vorphan = VariableDFG( :orphan, TestVariableType1(); tags = v1_tags, @@ -285,7 +279,7 @@ function DFGVariableSCA() # v3.states[:default].bw[1] = [1.0;1.0] @test getLabel(v1) == v1_lbl - @test getTags(v1) == v1_tags + @test DFG.refTags(v1) === v1_tags @test getTimestamp(v1) == v1.timestamp @@ -301,8 +295,8 @@ function DFGVariableSCA() #TODO here for now, don't reccomend usage. testTags = [:tag1, :tag2] - @test setTags!(v3, testTags) == Set(testTags) - @test setTags!(v3, Set(testTags)) == Set(testTags) + @test DFG.mergeTags!(v3, testTags) == 2 + @test DFG.mergeTags!(v3, Set(testTags)) == 2 #NOTE a variable's timestamp is considered similar to its label. setTimestamp! (not implemented) would create a new variable and call mergeVariable! # @test getTimestamp(v1ts) == testTimestamp @@ -334,7 +328,7 @@ function DFGFactorSCA() # "DFG Factor" # Constructors - #VariableCompute solvable default to 1, but Factor to 0, is that correct + #VariableDFG solvable default to 1, but Factor to 0, is that correct f1_lbl = :abf1 f1_tags = Set([:FACTOR]) testTimestamp = now(localzone()) @@ -359,7 +353,7 @@ function DFGFactorSCA() # we should perhaps prevent an empty vos @test getLabel(f1) == f1_lbl - @test getTags(f1) == f1_tags + @test DFG.refTags(f1) === f1_tags @test getTimestamp(f1) == f1.timestamp @@ -373,10 +367,9 @@ function DFGFactorSCA() @test typeof(getObservation(f1)) == TestFunctorInferenceType1{TestBelief} - #TODO here for now, don't recommend usage. testTags = [:tag1, :tag2] - @test setTags!(f1, testTags) == Set(testTags) - @test setTags!(f1, Set(testTags)) == Set(testTags) + @test DFG.mergeTags!(f1, testTags) == 2 + @test DFG.mergeTags!(f1, Set(testTags)) == 2 #follow with mergeFactor!(fg, v1ts) @@ -415,7 +408,7 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) # test getindex @test getLabel(fg[getLabel(v1)]) == getLabel(v1) - fnope = FactorCompute(:broken, [:a, :nope], TestFunctorInferenceType1()) + fnope = FactorDFG(:broken, [:a, :nope], TestFunctorInferenceType1()) @test_throws LabelNotFoundError addFactor!(fg, fnope) @test addFactor!(fg, f1) == f1 @@ -477,7 +470,7 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) @test addFactor!(fg, f0) == f0 - if isa(v1, VariableCompute) + if isa(v1, VariableDFG) #TODO decide if this should be @error or other type @test_throws LabelNotFoundError getVariable(fg, :a, :missingfoo) else @@ -534,7 +527,7 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) @test ls(fg) == listVariables(fg) @test lsf(fg) == listFactors(fg) - if getVariable(fg, ls(fg)[1]) isa VariableCompute + if getVariable(fg, ls(fg)[1]) isa VariableDFG @test :default in DFG.listStates(fg) @test :default in DFG.listStates(fg; labelFilter = contains("default") ∘ string) @test :default in DFG.listStates(fg) @@ -553,16 +546,17 @@ end function tagsTestBlock!(fg, v1, v1_tags) # "tags" # - v1Tags = deepcopy(getTags(v1)) + v1Tags = deepcopy(DFG.refTags(v1)) @test issetequal(v1Tags, v1_tags) @test issetequal(listTags(fg, :a), v1Tags) @test issetequal(mergeTags!(fg, :a, [:TAG]), v1Tags ∪ [:TAG]) @test issetequal(deleteTags!(fg, :a, [:TAG]), v1Tags) @test emptyTags!(fg, :a) == Set{Symbol}() - v2Tags = [listTags(fg, :b)...] - @test hasTags(fg, :b, [v2Tags...]) - @test hasTags(fg, :b, [:LANDMARK, :TAG], matchAll = false) + v2Tags = listTags(fg, :b) + @test hasTags(fg, :b, v2Tags) + @test hasTags(fg, :b, [:LANDMARK]) + @test !hasTags(fg, :b, [:LANDMARK, :TAG]) @test listNeighbors(fg, :abf1; tagsFilter = ⊇([:LANDMARK])) == [:b] @test isempty(listNeighbors(fg, :abf1; tagsFilter = ⊇([:LANDMARK, :TAG]))) @@ -572,24 +566,34 @@ function tagsTestBlock!(fg, v1, v1_tags) @test issetequal(listFactorTags(fg, :abf1), listTags(fg, :abf1)) # Test mergeVariableTags! and mergeFactorTags! - initialVarTags = listVariableTags(fg, :a) @test mergeVariableTags!(fg, :a, [:NEW_VAR_TAG]) == 1 @test :NEW_VAR_TAG ∈ listVariableTags(fg, :a) + @test hasVariableTags(fg, :a, [:NEW_VAR_TAG]) + @test deleteVariableTags!(fg, :a, [:NEW_VAR_TAG]) == 1 + @test !hasVariableTags(fg, :a, [:NEW_VAR_TAG]) - initialFactorTags = listFactorTags(fg, :abf1) @test mergeFactorTags!(fg, :abf1, [:NEW_FACTOR_TAG]) == 1 @test :NEW_FACTOR_TAG ∈ listFactorTags(fg, :abf1) + @test hasFactorTags(fg, :abf1, [:NEW_FACTOR_TAG]) + @test deleteFactorTags!(fg, :abf1, [:NEW_FACTOR_TAG]) == 1 + @test !hasFactorTags(fg, :abf1, [:NEW_FACTOR_TAG]) - # @test listGraphTags(fg) isa Vector{Symbol} - # @test listAgentTags(fg) isa Vector{Symbol} - - initialGraphTags = length(listGraphTags(fg)) @test mergeGraphTags!(fg, [:GRAPH_TAG]) == 1 @test :GRAPH_TAG ∈ listGraphTags(fg) + @test hasGraphTags(fg, [:GRAPH_TAG]) + @test deleteGraphTags!(fg, [:GRAPH_TAG]) == 1 + @test !hasGraphTags(fg, [:GRAPH_TAG]) - initialAgentTags = length(listAgentTags(fg)) @test mergeAgentTags!(fg, [:AGENT_TAG]) == 1 @test :AGENT_TAG ∈ listAgentTags(fg) + @test hasAgentTags(fg, [:AGENT_TAG]) + @test deleteAgentTags!(fg, [:AGENT_TAG]) == 1 + @test !hasAgentTags(fg, [:AGENT_TAG]) + + @test listVariableTags(fg, :a) isa Vector{Symbol} + @test listFactorTags(fg, :abf1) isa Vector{Symbol} + @test listGraphTags(fg) isa Vector{Symbol} + @test listAgentTags(fg) isa Vector{Symbol} end function VSDTestBlock!(fg, v1) @@ -764,6 +768,10 @@ function DataEntriesTestBlock!(fg, v2) @test issetequal(listVariableBlobentries(fg, :a), [:key1, :key2]) @test listVariableBlobentries(fg, :b) == Symbol[:key2] + @test hasVariableBlobentry(fg, :a, :key1) + @test !hasVariableBlobentry(fg, :a, :nope) + @test_throws LabelNotFoundError hasVariableBlobentry(fg, :nope, :nope) + #delete @test deleteBlobentry!(v1, :key1) == 1 @test listVariableBlobentries(fg, getLabel(v1)) == Symbol[:key2] @@ -785,6 +793,23 @@ function DataEntriesTestBlock!(fg, v2) @test_throws LabelExistsError addVariableBlobentries!(fg, :a, [de2]) @test deleteVariableBlobentries!(fg, :a, [:key2]) == 1 + #Factor blobentries + @test addFactorBlobentry!(fg, :abf1, de1) == de1 + @test_throws LabelExistsError addFactorBlobentry!(fg, :abf1, de1) + @test de1 == getFactorBlobentry(fg, :abf1, getLabel(de1)) + @test_throws LabelNotFoundError getFactorBlobentry(fg, :abf1, :nope) + @test hasFactorBlobentry(fg, :abf1, getLabel(de1)) + @test !hasFactorBlobentry(fg, :abf1, :nope) + @test mergeFactorBlobentry!(fg, :abf1, de2_update) == 1 + @test listFactorBlobentries(fg, :abf1) == [getLabel(de1), getLabel(de2_update)] + @test deleteFactorBlobentry!(fg, :abf1, getLabel(de2_update)) == 1 + @test_throws LabelNotFoundError deleteFactorBlobentry!(fg, :abf1, getLabel(de2_update)) + @test getFactorBlobentries(fg, :abf1) == [de1] + @test getLabel.(addFactorBlobentries!(fg, :abf1, [de2])) == [getLabel(de2)] + @test mergeFactorBlobentries!(fg, :abf1, [de1, de2_update]) == 2 + @test deleteFactorBlobentries!(fg, :abf1, [getLabel(de1), getLabel(de2_update)]) == 2 + @test listFactorBlobentries(fg, :abf1) == Symbol[] + #graph blobentries @test addGraphBlobentry!(fg, de1) == de1 @test_throws LabelExistsError addGraphBlobentry!(fg, de1) @@ -1005,7 +1030,7 @@ function testGroup!(fg, v1, v2, f0, f1) # FIXME return: Symbol[:b, :b] == Symbol[:b] varNearTs = findVariableNearTimestamp(fg, now()) - @test_skip varNearTs[1][1] == [:b] + @test varNearTs[1][1] == [:b] ## SORT copied from CRUD @test all( @@ -1199,8 +1224,8 @@ function AdjacencyMatricesTestBlock(fg) @test symdiff(v_ll, [:a, :b, :orphan]) == Symbol[] @test symdiff(f_ll, [:abf1]) == Symbol[] - # Only do solvable tests on VariableCompute - if isa(getVariable(fg, :a), VariableCompute) + # Only do solvable tests on VariableDFG + if isa(getVariable(fg, :a), VariableDFG) # Filtered - REF DFG #201 adjMat, v_ll, f_ll = getBiadjacencyMatrix(fg; solvableFilter = >=(0)) @test size(adjMat) == (1, 3) @@ -1218,7 +1243,7 @@ end # Now make a complex graph for connectivity tests function connectivityTestGraph( ::Type{T}; - VARTYPE = VariableCompute, + VARTYPE = VariableDFG, FACTYPE = FactorCompute, ) where {T <: AbstractDFG}#InMemoryDFGTypes #settings @@ -1284,7 +1309,7 @@ end # dfg, verts, facs = connectivityTestGraph(testDFGAPI) -function GettingNeighbors(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = FactorCompute) +function GettingNeighbors(testDFGAPI; VARTYPE = VariableDFG, FACTYPE = FactorCompute) # "Getting Neighbors" dfg, verts, facs = connectivityTestGraph(testDFGAPI; VARTYPE = VARTYPE, FACTYPE = FACTYPE) @@ -1300,7 +1325,7 @@ function GettingNeighbors(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = Facto # Solvable #TODO if not a GraphsDFG with and summary or skeleton - if VARTYPE == VariableCompute + if VARTYPE == VariableDFG @test listNeighbors(dfg, :x5; solvableFilter = >=(2)) == Symbol[] @test issetequal( listNeighbors(dfg, :x5; solvableFilter = >=(0)), @@ -1316,7 +1341,7 @@ function GettingNeighbors(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = Facto end #TODO confirm these tests are covered somewhere then delete -# function GettingSubgraphs(testDFGAPI; VARTYPE=VariableCompute, FACTYPE=FactorCompute) +# function GettingSubgraphs(testDFGAPI; VARTYPE=VariableDFG, FACTYPE=FactorCompute) # # # "Getting Subgraphs" # dfg, verts, facs = connectivityTestGraph(testDFGAPI, VARTYPE=VARTYPE, FACTYPE=FACTYPE) @@ -1338,7 +1363,7 @@ end # @test symdiff([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == [] # # #TODO if not a GraphsDFG with and summary or skeleton -# if VARTYPE == VariableCompute +# if VARTYPE == VariableDFG # # DFG issue #201 Test include orphan factors with filtering - should only return x7 with solvable=1 # @test_broken begin # dfgSubgraph = getSubgraphAroundNode(dfg, getFactor(dfg, :x7x8f1), 1, true, solvable=0) @@ -1366,7 +1391,7 @@ end # # end -function BuildingSubgraphs(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = FactorCompute) +function BuildingSubgraphs(testDFGAPI; VARTYPE = VariableDFG, FACTYPE = FactorCompute) # "Getting Subgraphs" dfg, verts, facs = @@ -1385,7 +1410,7 @@ function BuildingSubgraphs(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = Fact @test symdiff([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == [] #TODO if not a GraphsDFG with and summary or skeleton - if VARTYPE == VariableCompute + if VARTYPE == VariableDFG dfgSubgraph = buildSubgraph(testDFGAPI, dfg, [:x8], 2; solvable = 1) @test issetequal([:x7], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) #end if not a GraphsDFG with and summary or skeleton @@ -1402,7 +1427,7 @@ function BuildingSubgraphs(testDFGAPI; VARTYPE = VariableCompute, FACTYPE = Fact end #TODO buildSubgraph default constructors for skeleton and summary - if VARTYPE == VariableCompute + if VARTYPE == VariableDFG dfgSubgraph = buildSubgraph(dfg, [:x1, :x2, :x1x2f1]) @test issetequal([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) @@ -1451,7 +1476,7 @@ function ProducingDotFiles( v1 = nothing, v2 = nothing, f1 = nothing; - VARTYPE = VariableCompute, + VARTYPE = VariableDFG, FACTYPE = FactorCompute, ) # "Producing Dot Files" @@ -1476,7 +1501,7 @@ function ProducingDotFiles( addVariable!(dotdfg, v2) # FIXME, fix deprecation # ┌ Warning: addFactor!(dfg, variables, factor) is deprecated, use addFactor!(dfg, factor) - # │ caller = ProducingDotFiles(testDFGAPI::Type{GraphsDFG}, v1::Nothing, v2::Nothing, f1::Nothing; VARTYPE::Type{VariableCompute}, FACTYPE::Type{FactorCompute}) at testBlocks.jl:1440 + # │ caller = ProducingDotFiles(testDFGAPI::Type{GraphsDFG}, v1::Nothing, v2::Nothing, f1::Nothing; VARTYPE::Type{VariableDFG}, FACTYPE::Type{FactorCompute}) at testBlocks.jl:1440 # └ @ Main ~/.julia/dev/DistributedFactorGraphs/test/testBlocks.jl:1440 addFactor!(dotdfg, f1) #NOTE hardcoded toDot will have different results so test Graphs seperately