From a4354905a1f429e5aec1105a7a6c0a4bd5d5418d Mon Sep 17 00:00:00 2001 From: Johannes Terblanche Date: Thu, 26 Feb 2026 16:35:34 +0200 Subject: [PATCH 1/2] Cleanup, fixes and better listNeighborhood --- src/Common.jl | 19 +- src/DataBlobs/entities/BlobEntry.jl | 4 +- src/DataBlobs/services/BlobStores.jl | 20 +- src/Deprecated.jl | 7 + src/DistributedFactorGraphs.jl | 359 +++++++++++++-------------- src/FileDFG/services/FileDFG.jl | 6 +- src/GraphsDFG/GraphsDFG.jl | 13 + src/GraphsDFG/entities/GraphsDFG.jl | 17 +- src/GraphsDFG/services/GraphsDFG.jl | 59 +++-- src/services/AbstractDFG.jl | 106 ++++---- src/services/Bloblet.jl | 1 + src/services/CustomPrinting.jl | 7 +- src/services/DFGFactor.jl | 3 +- src/services/DFGVariable.jl | 9 + src/services/Tags.jl | 2 +- src/services/find.jl | 29 +-- src/services/list.jl | 17 +- test/testBlocks.jl | 22 +- 18 files changed, 375 insertions(+), 325 deletions(-) diff --git a/src/Common.jl b/src/Common.jl index 86d6337c..ea66bd7c 100644 --- a/src/Common.jl +++ b/src/Common.jl @@ -182,13 +182,30 @@ function solveGraphParametric! end # delta timestamps calcDeltatime(from::Nanosecond, to::Nanosecond) = Dates.value(to - from) / 10^9 + +function calcDeltatime_ns(from::TimeDateZone, to::TimeDateZone) + # TODO (-)(x::TimeDateZone, y::TimeDateZone) was very slow so manually calculated here + # return Dates.value(convert(Nanosecond, to - from)) / 10^9 + # calculate the "fast part" (microsecond) of the delta timestamp in nanoseconds + fast_to = convert(Nanosecond, Microsecond(to)) + Nanosecond(to) + fast_from = convert(Nanosecond, Microsecond(from)) + Nanosecond(from) + delta_fast = fast_to - fast_from + # calculate the "slow part" (zoned date time) of the delta timestamp in nanoseconds + delta_zoned = convert(Nanosecond, ZonedDateTime(to) - ZonedDateTime(from)) + return delta_zoned + delta_fast +end + function calcDeltatime(from::TimeDateZone, to::TimeDateZone) - return Dates.value(convert(Nanosecond, to - from)) / 10^9 + # TODO (-)(x::TimeDateZone, y::TimeDateZone) was very slow so manually calculated here + # return Dates.value(convert(Nanosecond, to - from)) / 10^9 + return Dates.value(calcDeltatime_ns(from, to)) / 10^9 end + calcDeltatime(from_node, to_node) = calcDeltatime(from_node.timestamp, to_node.timestamp) Timestamp(args...) = TimeDateZone(args...) Timestamp(t::Nanosecond, zone = tz"UTC") = Timestamp(Val(:unix), t, zone) +Timestamp(t::Microsecond, zone = tz"UTC") = Timestamp(Val(:unix), Nanosecond(t), zone) function Timestamp(epoch::Val{:unix}, t::Nanosecond, zone = tz"UTC") return TimeDateZone(TimeDate(1970) + t, zone) end diff --git a/src/DataBlobs/entities/BlobEntry.jl b/src/DataBlobs/entities/BlobEntry.jl index 9aaf2dd7..01b6c1d1 100644 --- a/src/DataBlobs/entities/BlobEntry.jl +++ b/src/DataBlobs/entities/BlobEntry.jl @@ -72,9 +72,9 @@ function Blobentry( size::Int64 = entry.size, origin::String = entry.origin, description::String = entry.description, - mimetype::String = entry.mimetype, + mimetype::MIME = entry.mimetype, metadata::JSONText = entry.metadata, - timestamp::ZonedDateTime = entry.timestamp, + timestamp::TimeDateZone = entry.timestamp, version = entry.version, ) return Blobentry(; diff --git a/src/DataBlobs/services/BlobStores.jl b/src/DataBlobs/services/BlobStores.jl index b831ce0e..6f506d6e 100644 --- a/src/DataBlobs/services/BlobStores.jl +++ b/src/DataBlobs/services/BlobStores.jl @@ -124,7 +124,7 @@ end FolderStore(label::Symbol, folder::String) = FolderStore{Vector{UInt8}}(label, folder) function FolderStore(foldername::String; label::Symbol = :default, createfolder = true) - storepath = joinpath(foldername, string(label)) + storepath = expanduser(joinpath(foldername, string(label))) if createfolder && !isdir(storepath) @info "Folder '$storepath' doesn't exist - creating." # create new folder @@ -134,11 +134,11 @@ function FolderStore(foldername::String; label::Symbol = :default, createfolder end function blobfilename(store::FolderStore, blobid::UUID) - return joinpath(store.folder, string(store.label), string(blobid)) + return expanduser(joinpath(store.folder, string(store.label), string(blobid))) end function getBlob(store::FolderStore{T}, blobid::UUID) where {T} - blobfilename = joinpath(store.folder, string(store.label), string(blobid)) + blobfilename = expanduser(joinpath(store.folder, string(store.label), string(blobid))) tombstonefile = blobfilename * ".deleted" if isfile(tombstonefile) throw(IdNotFoundError("Blob (deleted)", blobid)) @@ -152,7 +152,7 @@ function getBlob(store::FolderStore{T}, blobid::UUID) where {T} end function addBlob!(store::FolderStore{T}, blobid::UUID, data::T) where {T} - blobfilename = joinpath(store.folder, string(store.label), string(blobid)) + blobfilename = expanduser(joinpath(store.folder, string(store.label), string(blobid))) if isfile(blobfilename) throw(IdExistsError("Blob", blobid)) else @@ -165,7 +165,7 @@ end function deleteBlob!(store::FolderStore{T}, blobid::UUID) where {T} # Tombstone pattern: instead of deleting the file, create a tombstone marker file - blobfilename = joinpath(store.folder, string(store.label), string(blobid)) + blobfilename = expanduser(joinpath(store.folder, string(store.label), string(blobid))) tombstonefile = blobfilename * ".deleted" if isfile(blobfilename) # Remove the actual blob file @@ -185,14 +185,14 @@ function deleteBlob!(store::FolderStore{T}, blobid::UUID) where {T} end function hasBlob(store::FolderStore, blobid::UUID) - blobfilename = joinpath(store.folder, string(store.label), string(blobid)) + blobfilename = expanduser(joinpath(store.folder, string(store.label), string(blobid))) return isfile(blobfilename) end hasBlob(store::FolderStore, entry::Blobentry) = hasBlob(store, entry.blobid) function listBlobs(store::FolderStore) - folder = joinpath(store.folder, string(store.label)) + folder = expanduser(joinpath(store.folder, string(store.label))) # Parse folder to only include UUIDs automatically excluding tombstone files this way. blobids = UUID[] for filename in readdir(folder) @@ -249,11 +249,11 @@ listBlobs(store::InMemoryBlobstore) = collect(keys(store.blobs)) ##============================================================================== ## LinkStore Link blobid to a existing local folder ##============================================================================== - -struct LinkStore <: AbstractBlobstore{String} +#TODO consider using a deterministic blobid (uuid5) with ns stored in the csv? +@tags struct LinkStore <: AbstractBlobstore{String} label::Symbol csvfile::String - cache::Dict{UUID, String} + cache::Dict{UUID, String} & (json = (ignore = true,),) function LinkStore(label, csvfile) if !isfile(csvfile) diff --git a/src/Deprecated.jl b/src/Deprecated.jl index 867b43bc..3c468586 100644 --- a/src/Deprecated.jl +++ b/src/Deprecated.jl @@ -362,3 +362,10 @@ end args...; kwargs..., ) + +function getVariable(dfg::AbstractDFG, label::Symbol, stateLabel::Symbol) + Base.depwarn("getVariable with stateLabel is deprecated", :getVariable) + #TODO DFG v1.x will maybe use getVariable(dfg, label; stateLabelFilter) instead. + return getVariable(dfg, label) + # return getVariable(dfg, label; stateLabelFilter = ==(stateLabel)) +end diff --git a/src/DistributedFactorGraphs.jl b/src/DistributedFactorGraphs.jl index b4a63af6..4bca4ed6 100644 --- a/src/DistributedFactorGraphs.jl +++ b/src/DistributedFactorGraphs.jl @@ -87,7 +87,6 @@ export FactorDFG export FactorSummary export FactorSkeleton -#TODO Still pending timestamp field name decision export Blobentry export State @@ -96,28 +95,85 @@ export Agent ##------------------------------------------------------------------------------ ## Functions ##------------------------------------------------------------------------------ +##============================================================================== +## CRUD Matrix +# export addVariable!, getVariable, mergeVariable!, deleteVariable! +# export addVariables!, getVariables, mergeVariables!, deleteVariables! +# export addFactor!, getFactor, mergeFactor!, deleteFactor! +# export addFactors!, getFactors, mergeFactors!, deleteFactors! + +# export addState!, getState, mergeState!, deleteState! +# export addStates!, getStates, mergeStates!, deleteStates! + +# 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! +# export addFactorBlobentry!, getFactorBlobentry, mergeFactorBlobentry!, deleteFactorBlobentry! +# export addFactorBlobentries!, getFactorBlobentries, mergeFactorBlobentries!, deleteFactorBlobentries! + +# export addVariableBloblet!, getVariableBloblet, mergeVariableBloblet!, deleteVariableBloblet! +# export addVariableBloblets!, getVariableBloblets, mergeVariableBloblets!, deleteVariableBloblets! +# export addFactorBloblet!, getFactorBloblet, mergeFactorBloblet!, deleteFactorBloblet! +# export addFactorBloblets!, getFactorBloblets, mergeFactorBloblets!, deleteFactorBloblets! +# export addAgentBloblet!, getAgentBloblet, mergeAgentBloblet!, deleteAgentBloblet! +# export addAgentBloblets!, getAgentBloblets, mergeAgentBloblets!, deleteAgentBloblets! +# export addGraphBloblet!, getGraphBloblet, mergeGraphBloblet!, deleteGraphBloblet! +# export addGraphBloblets!, getGraphBloblets, mergeGraphBloblets!, deleteGraphBloblets! + +# list +# 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 + # v1 name, signiture, return, and error checked export addVariable! +export getVariable export mergeVariable! export deleteVariable! + export addVariables! export getVariables +export mergeVariables! +export deleteVariables! export addFactor! export getFactor export deleteFactor! +export mergeFactor! + export addFactors! export getFactors +export mergeFactors! +export deleteFactors! export addState! export getState export mergeState! export deleteState! + export addStates! +export getStates # TODO state filters not implemented yet export mergeStates! export deleteStates! +# has +export hasVariable export hasState +export hasFactor ## list export listVariables @@ -125,84 +181,140 @@ export listFactors export listStates ## -export getGraphBlobentry - export getObservation -## v1 name, signiture, and return +##------------------------------------------------------------------------------ +# Tags +export listVariableTags +export mergeVariableTags! +export deleteVariableTags! +export hasVariableTags -## v1 name only +export listFactorTags +export mergeFactorTags! +export deleteFactorTags! +export hasFactorTags -##------------------------------------------------------------------------------ -# Variable -##------------------------------------------------------------------------------ -export getVariable -export hasVariable -export mergeVariables! -##------------------------------------------------------------------------------ -## State -##------------------------------------------------------------------------------ -export getStates +export listGraphTags +export mergeGraphTags! +export deleteGraphTags! +export hasGraphTags -##------------------------------------------------------------------------------ -# Factor -##------------------------------------------------------------------------------ -export mergeFactor! -export mergeFactors! -export hasFactor +export listAgentTags +export mergeAgentTags! +export deleteAgentTags! +export hasAgentTags ##------------------------------------------------------------------------------ ## Blobentries ##------------------------------------------------------------------------------ export addVariableBlobentry! -export addVariableBlobentries! - export getVariableBlobentry -export getVariableBlobentries - export mergeVariableBlobentry! -export mergeVariableBlobentries! - export deleteVariableBlobentry! + +export addVariableBlobentries! +export getVariableBlobentries +export mergeVariableBlobentries! export deleteVariableBlobentries! -export addGraphBlobentry! -export addGraphBlobentries! -export addAgentBlobentry! -export addAgentBlobentries! +export addFactorBlobentry! +export getFactorBlobentry +export mergeFactorBlobentry! +export deleteFactorBlobentry! -export getGraphBlobentries -export getAgentBlobentry -export getAgentBlobentries +export addFactorBlobentries! +export getFactorBlobentries +export mergeFactorBlobentries! +export deleteFactorBlobentries! +export addGraphBlobentry! +export getGraphBlobentry export mergeGraphBlobentry! +export deleteGraphBlobentry! + +export addGraphBlobentries! +export getGraphBlobentries export mergeGraphBlobentries! -export mergeAgentBlobentry! -export mergeAgentBlobentries! +export deleteGraphBlobentries! -export deleteGraphBlobentry! +export addAgentBlobentry! +export getAgentBlobentry +export mergeAgentBlobentry! export deleteAgentBlobentry! -export deleteGraphBlobentries! + +export addAgentBlobentries! +export getAgentBlobentries +export mergeAgentBlobentries! export deleteAgentBlobentries! export listVariableBlobentries +export listFactorBlobentries export listGraphBlobentries export listAgentBlobentries export hasVariableBlobentry +export hasFactorBlobentry export hasGraphBlobentry export hasAgentBlobentry -export addFactorBlobentry! -export addFactorBlobentries! -export getFactorBlobentry -export getFactorBlobentries -export mergeFactorBlobentry! -export mergeFactorBlobentries! -export deleteFactorBlobentry! -export deleteFactorBlobentries! -export listFactorBlobentries -export hasFactorBlobentry +##------------------------------------------------------------------------------ +## Bloblets +##------------------------------------------------------------------------------ +export Bloblet +export getVariableBloblet +export addVariableBloblet! +export mergeVariableBloblet! +export deleteVariableBloblet! + +export addVariableBloblets! +export getVariableBloblets +export mergeVariableBloblets! +export deleteVariableBloblets! + +export addFactorBloblet! +export getFactorBloblet +export mergeFactorBloblet! +export deleteFactorBloblet! + +export addFactorBloblets! +export getFactorBloblets +export mergeFactorBloblets! +export deleteFactorBloblets! + +export getGraphBloblet +export addGraphBloblet! +export mergeGraphBloblet! +export deleteGraphBloblet! + +export addGraphBloblets! +export getGraphBloblets +export mergeGraphBloblets! +export deleteGraphBloblets! + +export getAgentBloblet +export addAgentBloblet! +export mergeAgentBloblet! +export deleteAgentBloblet! + +export addAgentBloblets! +export getAgentBloblets +export mergeAgentBloblets! +export deleteAgentBloblets! + +export listVariableBloblets +export listFactorBloblets +export listGraphBloblets +export listAgentBloblets + +# export hasVariableBloblet +# export hasFactorBloblet +# export hasGraphBloblet +# export hasAgentBloblet + +## v1 name, signiture, and return + +## v1 name only ##------------------------------------------------------------------------------ ## Blobstores and Blobs @@ -232,74 +344,6 @@ export DFG export GraphsDFGs export GraphsDFG -##============================================================================== -## CRUD Matrix -# export addVariable!, getVariable, mergeVariable!, deleteVariable! -# export addVariables!, getVariables, mergeVariables!, deleteVariables! -# export addFactor!, getFactor, mergeFactor!, deleteFactor! -# export addFactors!, getFactors, mergeFactors!, deleteFactors! - -# export addState!, getState, mergeState!, deleteState! -# export addStates!, getStates, mergeStates!, deleteStates! - -# 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! -# export addFactorBlobentry!, getFactorBlobentry, mergeFactorBlobentry!, deleteFactorBlobentry! -# export addFactorBlobentries!, getFactorBlobentries, mergeFactorBlobentries!, deleteFactorBlobentries! - -# export addVariableBloblet!, getVariableBloblet, mergeVariableBloblet!, deleteVariableBloblet! -# export addVariableBloblets!, getVariableBloblets, mergeVariableBloblets!, deleteVariableBloblets! -# export addFactorBloblet!, getFactorBloblet, mergeFactorBloblet!, deleteFactorBloblet! -# export addFactorBloblets!, getFactorBloblets, mergeFactorBloblets!, deleteFactorBloblets! -# export addAgentBloblet!, getAgentBloblet, mergeAgentBloblet!, deleteAgentBloblet! -# export addAgentBloblets!, getAgentBloblets, mergeAgentBloblets!, deleteAgentBloblets! -# export addGraphBloblet!, getGraphBloblet, mergeGraphBloblet!, deleteGraphBloblet! -# export addGraphBloblets!, getGraphBloblets, mergeGraphBloblets!, deleteGraphBloblets! - -## list -# 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 ##============================================================================== @@ -320,62 +364,12 @@ public FolderStore ##------------------------------------------------------------------------------ ## Tags ##------------------------------------------------------------------------------ -# tags is a set: get/list, merge, empty, and remove (we don't have add but merge) +# tags is a set: get/list, merge, delete (we don't have add but merge) public listTags public mergeTags! -public emptyTags! public deleteTags! - -##------------------------------------------------------------------------------ -## Bloblets -##------------------------------------------------------------------------------ -# currently these refer to variable Bloblets -#TODO Bloblet CRUD -export Bloblet -export getVariableBloblet -export addVariableBloblet! -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! +# public emptyTags! ##------------------------------------------------------------------------------ ## FileDFG @@ -390,8 +384,8 @@ export loadDFG ##------------------------------------------------------------------------------ #TODO is ls alias or more of a shorthand with extra functionality? # if shorthand kind of function it is likeley only DFG -export ls # alias for listVariables -export lsf # alias for listFactors +# public ls # alias for listVariables +# public lsf # alias for listFactors ##------------------------------------------------------------------------------ ## Other utility functions @@ -401,14 +395,14 @@ export lsf # alias for listFactors # addAgent! # deleteAgent! # listAgents +# getAgents # addGraph! # deleteGraph! # listGraphs -# getAgents +# getGraphs # getModel # getModels # addModel! -# getGraphs ##============================================================================== export @format_str # exported from FileIO @@ -418,6 +412,8 @@ export @defStateType #TODO Should this be exported? public refStates public getStateKind +public pack, unpack + # list of unstable functions not exported any more # will move to public or deprecate over time const unstable_functions::Vector{Symbol} = [ @@ -444,8 +440,8 @@ const unstable_functions::Vector{Symbol} = [ :findVariablesNearTimestamp, :findShortestPathDijkstra, :findFactorsBetweenNaive, - :getAgentLabel, - :getGraphLabel, + :getAgentLabel, #TODO check and mark as public + :getGraphLabel, #TODO check and mark as public :getDescription, :getSolverParams, :getHash, @@ -463,7 +459,6 @@ const unstable_functions::Vector{Symbol} = [ :getCoordinates, :getVariableLabelNumber,# TODO somewhat used, do we deprecate? :getfirstBlobentry,# TODO somewhat used, do we deprecate? - :getSolveInProgress,#TODO unused, do we deprecate? :isVariable, :isFactor, :isConnected, @@ -478,22 +473,19 @@ const unstable_functions::Vector{Symbol} = [ :printVariable, :printNode, :plotDFG, - :pack, - # :packVariable, - # :packFactor, :packBlob, :packState, - :unpack, :hasTags, - # :unpackVariable, - # :unpackFactor, :unpackBlob, :unpackState, + :emptyTags!, + :ls, + :lsf, :ls2, :lsfPriors, :listBlobentrySequence,# TODO somewhat used, do we deprecate? - :natural_lt, #TODO do we stable functions such as natural_lt or just mark as public - :sortDFG, #TODO do we stable functions such as natural_lt or just mark as public + :natural_lt, #TODO do we export stable functions such as natural_lt or just mark as public + :sortDFG, #TODO do we export stable functions such as natural_lt or just mark as public :mergeGraph!, :buildSubgraph, :incrDataLabelSuffix,# TODO somewhat used, do we deprecate? @@ -529,6 +521,7 @@ const unstable_functions::Vector{Symbol} = [ :setGraphMetadata!, # :getSolverDataDict,# obsolete :getAddHistory, + :getSolveInProgress,#deprecated ] macro usingDFG(unstable = false) diff --git a/src/FileDFG/services/FileDFG.jl b/src/FileDFG/services/FileDFG.jl index a24c826d..7e1fe25c 100644 --- a/src/FileDFG/services/FileDFG.jl +++ b/src/FileDFG/services/FileDFG.jl @@ -57,7 +57,7 @@ function saveDFG(folder::AbstractString, dfg::AbstractDFG) next!(p) JSON.json("$savepath/solverparams.json", dfg.solverParams; style = DFGJSONStyle()) next!(p) - JSON.json("$savepath/blobstores.json", dfg.blobStores; style = DFGJSONStyle()) + JSON.json("$savepath/blobstores.json", dfg.blobstores; style = DFGJSONStyle()) next!(p) savedir = dirname(savepath) # is this a path of just local name? #344 -- workaround with unique names @@ -187,14 +187,14 @@ function loadDFG(file::AbstractString) style = DFGJSONStyle(), ) next!(progess) - blobStores = JSON.parsefile( + blobstores = JSON.parsefile( joinpath(loaddir, "blobstores.json"), Dict{Symbol, AbstractBlobstore}; style = DFGJSONStyle(), ) next!(progess) - dfg = GraphsDFG(; agent, graph, solverParams, blobStores) + dfg = GraphsDFG(; agent, graph, solverParams, blobstores) @debug "DFG.loadDFG is deleting a temp folder created during unzip, $loaddir" # cleanup temporary folder diff --git a/src/GraphsDFG/GraphsDFG.jl b/src/GraphsDFG/GraphsDFG.jl index 945e484f..b6825979 100644 --- a/src/GraphsDFG/GraphsDFG.jl +++ b/src/GraphsDFG/GraphsDFG.jl @@ -76,4 +76,17 @@ include("services/GraphsDFG.jl") # Exports export GraphsDFG +#FIXME maybe add a trait based on solver data for rebuilding factor cache and dispatch on it. +function DFG.rebuildFactorCache!( + dfg::GraphsDFG{NoSolverParams}, + factor::FactorDFG, + neighbors = [], +) + @warn( + "FactorCache not build, rebuildFactorCache! is not implemented for $(typeof(dfg)). `rebuildFactorCache!` is available in IncrementalInference.", + maxlog = 1 + ) + return nothing +end + end diff --git a/src/GraphsDFG/entities/GraphsDFG.jl b/src/GraphsDFG/entities/GraphsDFG.jl index b1831a0e..afa39f50 100644 --- a/src/GraphsDFG/entities/GraphsDFG.jl +++ b/src/GraphsDFG/entities/GraphsDFG.jl @@ -14,7 +14,7 @@ mutable struct GraphsDFG{ g::FactorGraph{Int, V, F} # addHistory::Vector{Symbol} #TODO: Discuss more - is this an audit trail? solverParams::T # Solver parameters - blobStores::Dict{Symbol, AbstractBlobstore} + blobstores::Dict{Symbol, AbstractBlobstore} #TODO note v0.29 changed from camelCase blobStores graph::Graphroot agent::Agent end @@ -35,7 +35,7 @@ function GraphsDFG{T, V, F}( g::FactorGraph{Int, V, F} = FactorGraph{Int, V, F}(); # addHistory::Vector{Symbol} = Symbol[], solverParams::T = T(), - blobStores = Dict{Symbol, AbstractBlobstore}(), + blobstores = Dict{Symbol, AbstractBlobstore}(), # graph graphLabel::Symbol = Symbol("graph_", string(uuid4())[1:6]), graphDescription::String = "", @@ -79,7 +79,7 @@ function GraphsDFG{T, V, F}( !DFG.isValidLabel(agentLabel) && throw(ArgumentError("'$agentLabel' is not a valid label")) - return GraphsDFG{T, V, F}(g, solverParams, blobStores, graph, agent) + return GraphsDFG{T, V, F}(g, solverParams, blobstores, graph, agent) end # GraphsDFG{T}(; kwargs...) where T <: AbstractDFGParams = GraphsDFG{T,VariableDFG,FactorDFG}(;kwargs...) @@ -97,3 +97,14 @@ function GraphsDFG( ) where {T} return GraphsDFG{T, VariableDFG, FactorDFG}(g; solverParams, kwargs...) end + +function GraphsDFG( + fg::GraphsDFG; + g = fg.g, + solverParams = fg.solverParams, + blobstores = fg.blobstores, + graph = fg.graph, + agent = fg.agent, +) + return GraphsDFG(g, solverParams, blobstores, graph, agent) +end diff --git a/src/GraphsDFG/services/GraphsDFG.jl b/src/GraphsDFG/services/GraphsDFG.jl index fbb8af39..2afb4314 100644 --- a/src/GraphsDFG/services/GraphsDFG.jl +++ b/src/GraphsDFG/services/GraphsDFG.jl @@ -92,14 +92,19 @@ function mergeVariable!(dfg::GraphsDFG, variable::AbstractGraphVariable) end function mergeFactor!(dfg::GraphsDFG, factor::AbstractGraphFactor) - if !haskey(dfg.g.factors, factor.label) + label = getLabel(factor) + if !haskey(dfg.g.factors, label) addFactor!(dfg, factor) - elseif dfg.g.factors[factor.label].variableorder != factor.variableorder - #TODO should we allow merging the factor neighbors or error as before? - error("Cannot update the factor, the neighbors are not the same.") - # We need to delete the factor if we are updating the neighbors - # deleteFactor!(dfg, factor.label) - # addFactor!(dfg, factor) + elseif DFG.getVariableOrder(dfg, label) != DFG.getVariableOrder(factor) + throw( + DomainError( + factor.variableorder, + "Cannot merge factor with label $(label): factor neighbors differ. " * + "Existing neighbors: $(DFG.getVariableOrder(dfg, label)), " * + "new neighbors: $(DFG.getVariableOrder(factor)), " * + "To mutate factor neighbors, delete and re-add the factor.", + ), + ) else dfg.g.factors[factor.label] = factor end @@ -214,15 +219,6 @@ function isConnected(dfg::GraphsDFG) # return length(Graphs.connected_components(dfg.g)) == 1 end -function listNeighbors( - dfg::GraphsDFG, - node::AbstractGraphNode; - solvable::Union{Nothing, Int} = nothing, - kwargs..., -) - return listNeighbors(dfg, node.label; solvable, kwargs...) -end - function listNeighbors( dfg::GraphsDFG, label::Symbol; @@ -265,8 +261,20 @@ function listNeighborhood( dfg::GraphsDFG, variableFactorLabels::Vector{Symbol}, distance::Int; - solvable::Union{Nothing, Int} = nothing, + solvableFilter::Union{Nothing, Function} = nothing, + tagsFilter::Union{Nothing, Function} = nothing, + solvable::Union{Nothing, Int} = nothing, #TODO deprecated for solvableFilter v0.29 ) + if !isnothing(solvable) + Base.depwarn( + "solvable kwarg is deprecated, use kwarg `solvableFilter = (>=solvable)` instead", #v0.29 + :listNeighbors, + ) + !isnothing(solvableFilter) && + error("Cannot use both solvable and solvableFilter kwargs.") + solvableFilter = >=(solvable) + end + # find neighbors at distance to add nbhood = Int[] @@ -276,10 +284,19 @@ function listNeighborhood( allvarfacs = [dfg.g.labels[id] for id in nbhood] - !isnothing(solvable) && - filter!(nlbl -> (getSolvable(dfg, nlbl) >= solvable), allvarfacs) + filterDFG!(allvarfacs, solvableFilter, l->getSolvable(dfg, l)) + filterDFG!(allvarfacs, tagsFilter, l->listTags(dfg, l)) + + variableLabels = intersect(listVariables(dfg), allvarfacs) + factorLabels = intersect(listFactors(dfg), allvarfacs) - return allvarfacs + # if filterOrphans + # filter!(factorLabels) do lbl + # issubset(getVariableOrder(fg, lbl), variableLabels) + # end + # end + + return variableLabels, factorLabels end # TODO copy GraphsDFG to GraphsDFG overwrite @@ -294,7 +311,7 @@ end # Biadjacency Matrix https://en.wikipedia.org/wiki/Adjacency_matrix#Of_a_bipartite_graph function getBiadjacencyMatrix( dfg::GraphsDFG; - solvable::Union{Nothing, Int} = nothing, + solvable::Union{Nothing, Int} = nothing, #TODO deprecated for solvableFilter v0.29 solvableFilter = isnothing(solvable) ? nothing : >=(solvable), varLabels = listVariables(dfg; solvableFilter), factLabels = listFactors(dfg; solvableFilter), diff --git a/src/services/AbstractDFG.jl b/src/services/AbstractDFG.jl index 36b7f486..1ebdec72 100644 --- a/src/services/AbstractDFG.jl +++ b/src/services/AbstractDFG.jl @@ -91,7 +91,7 @@ end ##============================================================================== # AbstractBlobstore should have label or overwrite getLabel -refBlobstores(dfg::AbstractDFG) = dfg.blobStores +refBlobstores(dfg::AbstractDFG) = dfg.blobstores function getBlobstore(dfg::AbstractDFG, storeLabel::Symbol) store = get(refBlobstores(dfg), storeLabel, nothing) @@ -277,11 +277,9 @@ Get the variables in the DFG as a Vector, supporting various filters. Arguments - `regexFilt`: Optional Regex to filter variable labels (deprecated, use `labelFilter` instead). Keyword arguments -- `tags`: Vector of tags; only variables with at least one matching tag are returned. -- `solvable`: Optional Int; only variables with `solvable >= solvable` are returned. - `solvableFilter`: Optional function to filter on the `solvable` property, eg `>=(1)`. - `labelFilter`: Optional function to filter on label e.g., `contains(r"x1")`. -- `tagsFilter`: Optional function to filter on tags, eg. `⊇([:x1])`. +- `tagsFilter`: Optional function to filter on tags, eg. `⊇([:POSE])`. - `typeFilter`: Optional function to filter on the variable type. Returns @@ -343,10 +341,13 @@ function isConnected end """ $(SIGNATURES) Retrieve a list of labels of the immediate neighbors around a given variable or factor specified by its label. -Implement `listNeighbors(dfg::AbstractDFG, label::Symbol; solvable::Int = 0)` +Implement `listNeighbors(dfg::AbstractDFG, label::Symbol; solvableFilter, tagsFilter)` """ function listNeighbors end +function listNeighbors(dfg::AbstractDFG, node::AbstractGraphNode; kwargs...) + return listNeighbors(dfg, node.label; kwargs...) +end ##------------------------------------------------------------------------------ ## copy and duplication ##------------------------------------------------------------------------------ @@ -355,26 +356,6 @@ function listNeighbors end ## CRUD Aliases ##------------------------------------------------------------------------------ -#TODO should this signiture be standardized or removed? -""" - $(SIGNATURES) -Get a VariableDFG with a specific solver key. -In memory types still return a reference, other types returns a variable with only stateLabel. -""" -function getVariable(dfg::AbstractDFG, label::Symbol, stateLabel::Symbol) - # TODO maybe change stateLabel param to stateLabelFilter - # function getVariable(dfg::AbstractDFG, label::Symbol; stateLabelFilter::Union{Nothing, ...} = nothing) - var = getVariable(dfg, label) - - if isa(var, VariableDFG) && !haskey(var.states, stateLabel) - throw(LabelNotFoundError("VariableNode", stateLabel)) - elseif !isa(var, VariableDFG) - @warn "getVariable(dfg, label, stateLabel) only supported for type VariableDFG." - end - - return var -end - function deleteVariable!(dfg::AbstractDFG, variable::AbstractGraphVariable) return deleteVariable!(dfg, variable.label) end @@ -599,9 +580,11 @@ function isPathFactorsHomogeneous(dfg::AbstractDFG, from::Symbol, to::Symbol) return (length(utyp) == 1), utyp end +#TODO add pruning filters that is applied during traversal. """ $(SIGNATURES) -Build a list of all unique neighbors inside 'distance' +Build a list of all unique neighbors inside 'distance'. Neighbors can be filtered by using keyword arguments, eg. [`tagsFilter`] and [`solvableFilter`]. +Filters are applied to final neighborhood result. Notes - Returns `Vector{Symbol}` @@ -612,7 +595,7 @@ Related: - [`deepcopyGraph`](@ref) - [`mergeGraph!`](@ref) """ -function listNeighborhood(dfg::AbstractDFG, label::Symbol, distance::Int) +function listNeighborhood(dfg::AbstractDFG, label::Symbol, distance::Int; filters...) neighborList = Set{Symbol}([label]) curList = Set{Symbol}([label]) @@ -620,43 +603,38 @@ function listNeighborhood(dfg::AbstractDFG, label::Symbol, distance::Int) newNeighbors = Set{Symbol}() for node in curList neighbors = listNeighbors(dfg, node) - for neighbor in neighbors - push!(neighborList, neighbor) - push!(newNeighbors, neighbor) - end + union!(neighborList, neighbors) + union!(newNeighbors, neighbors) end curList = newNeighbors end - return collect(neighborList) + + variableLabels = intersect(listVariables(dfg; filters...), neighborList) + factorLabels = intersect(listFactors(dfg; filters...), neighborList) + + return variableLabels, factorLabels end function listNeighborhood( dfg::AbstractDFG, variableFactorLabels::Vector{Symbol}, distance::Int; - solvable::Int = 0, + filters..., ) - # find neighbors at distance to add - neighbors = Set{Symbol}() if distance > 0 + variableLabels = Symbol[] + factorLabels = Symbol[] for l in variableFactorLabels - union!(neighbors, listNeighborhood(dfg, l, distance)) + varls, facls = listNeighborhood(dfg, l, distance; filters...) + union!(variableLabels, varls) + union!(factorLabels, facls) end + else + variableLabels = intersect(listVariables(dfg; filters...), variableFactorLabels) + factorLabels = intersect(listFactors(dfg; filters...), variableFactorLabels) end - allvarfacs = union(variableFactorLabels, neighbors) - - solvable != 0 && filter!(nlbl -> (getSolvable(dfg, nlbl) >= solvable), allvarfacs) - - return allvarfacs -end - -function listNeighbors( - dfg::AbstractDFG, - node::AbstractGraphNode; - solvable::Union{Nothing, Int} = nothing, -) - return listNeighbors(dfg, node.label; solvable) + return variableLabels, factorLabels end """ @@ -676,16 +654,25 @@ function buildSubgraph( dfg::AbstractDFG, variableFactorLabels::Vector{Symbol}, distance::Int = 0; - solvable::Int = 0, + solvableFilter::Union{Nothing, Function} = nothing, + tagsFilter::Union{Nothing, Function} = nothing, graphLabel::Symbol = Symbol(getGraphLabel(dfg), "_sub_$(string(uuid4())[1:6])"), + solvable = nothing, #TODO deprecated in v0.29 kwargs..., ) where {G <: AbstractDFG} - + if !isnothing(solvable) + Base.depwarn( + "solvable kwarg is deprecated, use kwarg `solvableFilter = (>=solvable)` instead", #v0.29 + :listNeighbors, + ) + !isnothing(solvableFilter) && + error("Cannot use both solvable and solvableFilter kwargs.") + solvableFilter = >=(solvable) + end #build up the neighborhood from variableFactorLabels - allvarfacs = listNeighborhood(dfg, variableFactorLabels, distance; solvable = solvable) + variableLabels, factorLabels = + listNeighborhood(dfg, variableFactorLabels, distance; solvableFilter, tagsFilter) - variableLabels = intersect(allvarfacs, listVariables(dfg)) - factorLabels = intersect(allvarfacs, listFactors(dfg)) # Copy the section of graph we want destDFG = deepcopyGraph(G, dfg, variableLabels, factorLabels; graphLabel, kwargs...) return destDFG @@ -718,21 +705,20 @@ function mergeGraph!( variableLabels::Vector{Symbol} = ls(sourceDFG), factorLabels::Vector{Symbol} = lsf(sourceDFG), distance::Int = 0; - solvable::Int = 0, + solvableFilter = nothing, + tagsFilter = nothing, kwargs..., ) # find neighbors at distance to add - allvarfacs = listNeighborhood( + sourceVariables, sourceFactors = listNeighborhood( sourceDFG, union(variableLabels, factorLabels), distance; - solvable = solvable, + solvableFilter, + tagsFilter, ) - sourceVariables = intersect(listVariables(sourceDFG), allvarfacs) - sourceFactors = intersect(listFactors(sourceDFG), allvarfacs) - copyGraph!( destDFG, sourceDFG, diff --git a/src/services/Bloblet.jl b/src/services/Bloblet.jl index 8242c068..7c9152b6 100644 --- a/src/services/Bloblet.jl +++ b/src/services/Bloblet.jl @@ -1,3 +1,4 @@ +# TODO add labelFilter to get_Bloblets ## ============================================================================== ## Variable Bloblets ## ============================================================================== diff --git a/src/services/CustomPrinting.jl b/src/services/CustomPrinting.jl index 202c08f9..efd3ec9e 100644 --- a/src/services/CustomPrinting.jl +++ b/src/services/CustomPrinting.jl @@ -184,12 +184,13 @@ end function Base.show(io::IO, ::MIME"text/plain", dfg::AbstractDFG) summary(io, dfg) + println(io) println(io, " AgentLabel: ", getAgentLabel(dfg)) - println(io, " FactorgraphLabel: ", getGraphLabel(dfg)) + println(io, " GraphLabel: ", getGraphLabel(dfg)) println(io, " Description: ", getDescription(dfg)) println(io, " Nr variables: ", length(ls(dfg))) println(io, " Nr factors: ", length(lsf(dfg))) - println(io, " Agent Metadata: ", listAgentBloblets(dfg)) - println(io, " Graph Metadata: ", listGraphBloblets(dfg)) + println(io, " Agent Bloblets: ", listAgentBloblets(dfg)) + println(io, " Graph Bloblets: ", listGraphBloblets(dfg)) return end diff --git a/src/services/DFGFactor.jl b/src/services/DFGFactor.jl index ff43d134..f40c2189 100644 --- a/src/services/DFGFactor.jl +++ b/src/services/DFGFactor.jl @@ -167,14 +167,13 @@ getManifold(f::AbstractGraphFactor) = getManifold(getObservation(f)) ## variableorder ##------------------------------------------------------------------------------ -#TODO perhaps making variableorder imutable (NTuple) will be a save option """ $SIGNATURES Get the variable ordering for this factor. Should be equivalent to listNeighbors unless something was deleted in the graph. """ -getVariableOrder(fct::FactorDFG) = fct.variableorder +getVariableOrder(fct::AbstractGraphFactor) = fct.variableorder getVariableOrder(dfg::AbstractDFG, fct::Symbol) = getVariableOrder(getFactor(dfg, fct)) ##------------------------------------------------------------------------------ diff --git a/src/services/DFGVariable.jl b/src/services/DFGVariable.jl index 8bf4bfb8..4292b527 100644 --- a/src/services/DFGVariable.jl +++ b/src/services/DFGVariable.jl @@ -104,10 +104,16 @@ macro defStateTypeN(structname, manifold, point_identity) ) end +#TODO why this convert? rather enforce explicit use of getManifold function Base.convert( ::Type{<:AbstractManifold}, ::Union{<:T, Type{<:T}}, ) where {T <: StateType} + #TODO Deprecate v0.29 + Base.depwarn( + "convert(AbstractManifold, StateType) is deprecated, use getManifold instead", + :convert, + ) return getManifold(T) end @@ -383,6 +389,9 @@ end ## CRUD: get, add, update, delete ##------------------------------------------------------------------------------ hasState(v::VariableDFG, label::Symbol) = haskey(v.states, label) +function hasState(dfg::AbstractDFG, variableLabel::Symbol, label::Symbol) + return hasState(getVariable(dfg, variableLabel), label) +end function getState(v::VariableDFG, label::Symbol) !haskey(refStates(v), label) && throw(LabelNotFoundError("State", label)) diff --git a/src/services/Tags.jl b/src/services/Tags.jl index dd92fe34..65d27657 100644 --- a/src/services/Tags.jl +++ b/src/services/Tags.jl @@ -129,12 +129,12 @@ function hasAgentTags(dfg::AbstractDFG, tags::Vector{Symbol}) end ## - function listTags(dfg::AbstractDFG, sym::Symbol) getFnc = isVariable(dfg, sym) ? getVariable : getFactor return listTags(getFnc(dfg, sym)) end +#TODO FIXME for DFGv1, merge and delete should return the number of tags added/removed. function mergeTags!(dfg::InMemoryDFGTypes, sym::Symbol, tags) getFnc = isVariable(dfg, sym) ? getVariable : getFactor return union!(refTags(getFnc(dfg, sym)), tags) diff --git a/src/services/find.jl b/src/services/find.jl index eefb2ff1..9c317c43 100644 --- a/src/services/find.jl +++ b/src/services/find.jl @@ -14,13 +14,10 @@ function findClosestTimestamp( ) where {S, T} # # build matrix of delta times, ranges on rows x vars on columns - DT = Array{Nanosecond, 2}(undef, length(setA), length(setB)) - for i = 1:length(setA), j = 1:length(setB) - DT[i, j] = setB[j][1] - setA[i][1] + DT = map(Iterators.product(setA, setB)) do (a, b) + return abs(DFG.calcDeltatime_ns(a[1], b[1])) end - DT .= abs.(DT) - # absolute time differences # DTi = (x->x.value).(DT) .|> abs @@ -51,7 +48,7 @@ ls, listVariables, findClosestTimestamp """ function findVariablesNearTimestamp( dfg::AbstractDFG, - timest::TimeDateZone; + query_timestamp::TimeDateZone; labelFilter::Union{Nothing, Function} = nothing, tagsFilter::Union{Nothing, Function} = nothing, solvableFilter::Union{Nothing, Function} = nothing, @@ -59,11 +56,11 @@ function findVariablesNearTimestamp( ) # # get the variable labels based on filters - syms = listVariables(dfg; labelFilter, tagsFilter, solvableFilter) + vls = listVariables(dfg; labelFilter, tagsFilter, solvableFilter) # compile timestamps with label - # vars = map( x->getVariable(dfg, x), syms ) - timeset = map(x -> (getTimestamp(getVariable(dfg, x)), x), syms) - mask = BitArray{1}(undef, length(syms)) + # vars = map( x->getVariable(dfg, x), vls ) + timeset = map(x -> (getTimestamp(getVariable(dfg, x)), x), vls) + mask = BitArray{1}(undef, length(vls)) fill!(mask, true) RET = Vector{Tuple{Vector{Symbol}, Nanosecond}}() @@ -72,8 +69,8 @@ function findVariablesNearTimestamp( NUMBER = number while 0 < CORRS + NUMBER # get closest - link, mdt, corrs = findClosestTimestamp([(timest, 0)], timeset[mask]) - newsym = syms[link[2]] + link, mdt, corrs = findClosestTimestamp([(query_timestamp, 0)], timeset[mask]) + newsym = vls[link[2]] union!(SYMS, !isa(newsym, Vector) ? [newsym] : newsym) mask[link[2]] = false CORRS = corrs - 1 @@ -90,11 +87,15 @@ end function findVariablesNearTimestamp( dfg::AbstractDFG, - timest::DateTime; + query_timestamp::DateTime; timezone = tz"UTC", kwargs..., ) - return findVariablesNearTimestamp(dfg, TimeDateZone(timest, timezone); kwargs...) + return findVariablesNearTimestamp( + dfg, + TimeDateZone(query_timestamp, timezone); + kwargs..., + ) end ##============================================================================== diff --git a/src/services/list.jl b/src/services/list.jl index fce163f1..3d76ca81 100644 --- a/src/services/list.jl +++ b/src/services/list.jl @@ -121,16 +121,23 @@ function ls(dfg::AbstractDFG, ::Type{T}) where {T <: AbstractObservation} return lsf(dfg, T) end +# TODO listNeighborsSecondary or listNeighborsOfNeighbors """ $(SIGNATURES) -Helper to return neighbors at distance 2 around a given node. +List the second order neighbors of a given node. """ -function ls2(dfg::AbstractDFG, label::Symbol) - l2 = listNeighborhood(dfg, label, 2) - l1 = listNeighborhood(dfg, label, 1) +function listNeighborsSecondary(dfg::AbstractDFG, label::Symbol) + varls2, facls2 = listNeighborhood(dfg, label, 2) + varls1, facls1 = listNeighborhood(dfg, label, 1) + l1 = union(varls1, facls1) + l2 = union(varls2, facls2) return setdiff(l2, l1) end -ls2(dfg::AbstractDFG, v::AbstractGraphNode) = ls2(dfg, getLabel(v)) +function listNeighborsSecondary(dfg::AbstractDFG, v::AbstractGraphNode) + return listNeighborsSecondary(dfg, getLabel(v)) +end + +ls2(args...) = listNeighborsSecondary(args...) """ $SIGNATURES diff --git a/test/testBlocks.jl b/test/testBlocks.jl index 33714dd7..b8de27d7 100644 --- a/test/testBlocks.jl +++ b/test/testBlocks.jl @@ -446,7 +446,7 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) f2_mod = typeof(f2)(f2.label, (:a,)) end - @test_throws ErrorException mergeFactor!(fg, f2_mod) + @test_throws DomainError mergeFactor!(fg, f2_mod) @test issetequal(lsf(fg), [:bcf1, :abf1]) # Extra timestamp functions https://github.com/JuliaRobotics/DistributedFactorGraphs.jl/issues/315 @@ -472,21 +472,9 @@ function VariablesandFactorsCRUD_SET!(fg, v1, v2, v3, f0, f1, f2) @test ndel == 1 @test getVariable(fg, :a) == v1 - @test getVariable(fg, :a, :default) == v1 @test addFactor!(fg, f0) == f0 - if isa(v1, VariableDFG) - #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 VariableDFG") getVariable( - fg, - :a, - :missingfoo, - ) - end - @test getFactor(fg, :abf1) == f1 @test_throws LabelNotFoundError getVariable(fg, :c) @@ -1397,19 +1385,19 @@ function BuildingSubgraphs(testDFGAPI; VARTYPE = VariableDFG, FACTYPE = FactorCo # Subgraphs dfgSubgraph = buildSubgraph(testDFGAPI, dfg, [verts[1].label], 2) # Only returns x1 and x2 - @test symdiff([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == [] + @test issetequal([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) # dfgSubgraph = buildSubgraph(testDFGAPI, dfg, [:x1, :x2, :x1x2f1]) # Only returns x1 and x2 - @test symdiff([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == [] + @test issetequal([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) dfgSubgraph = buildSubgraph(testDFGAPI, dfg, [:x1x2f1], 1) # Only returns x1 and x2 - @test symdiff([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) == [] + @test issetequal([:x1, :x1x2f1, :x2], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) #TODO if not a GraphsDFG with and summary or skeleton if VARTYPE == VariableDFG - dfgSubgraph = buildSubgraph(testDFGAPI, dfg, [:x8], 2; solvable = 1) + dfgSubgraph = buildSubgraph(testDFGAPI, dfg, [:x8], 2; solvableFilter = >=(1)) @test issetequal([:x7], [ls(dfgSubgraph)..., lsf(dfgSubgraph)...]) #end if not a GraphsDFG with and summary or skeleton end From dab77796ee3c5a2b3e02159a19e911b3b8e7c47c Mon Sep 17 00:00:00 2001 From: Johannes Terblanche <6612981+Affie@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:03:10 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/GraphsDFG/GraphsDFG.jl | 2 +- src/GraphsDFG/services/GraphsDFG.jl | 4 ++-- src/services/AbstractDFG.jl | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/GraphsDFG/GraphsDFG.jl b/src/GraphsDFG/GraphsDFG.jl index b6825979..5d72a05f 100644 --- a/src/GraphsDFG/GraphsDFG.jl +++ b/src/GraphsDFG/GraphsDFG.jl @@ -83,7 +83,7 @@ function DFG.rebuildFactorCache!( neighbors = [], ) @warn( - "FactorCache not build, rebuildFactorCache! is not implemented for $(typeof(dfg)). `rebuildFactorCache!` is available in IncrementalInference.", + "FactorCache not built, rebuildFactorCache! is not implemented for $(typeof(dfg)). `rebuildFactorCache!` is available in IncrementalInference.", maxlog = 1 ) return nothing diff --git a/src/GraphsDFG/services/GraphsDFG.jl b/src/GraphsDFG/services/GraphsDFG.jl index 2afb4314..a0e22fa9 100644 --- a/src/GraphsDFG/services/GraphsDFG.jl +++ b/src/GraphsDFG/services/GraphsDFG.jl @@ -106,7 +106,7 @@ function mergeFactor!(dfg::GraphsDFG, factor::AbstractGraphFactor) ), ) else - dfg.g.factors[factor.label] = factor + dfg.g.factors[label] = factor end return 1 @@ -268,7 +268,7 @@ function listNeighborhood( if !isnothing(solvable) Base.depwarn( "solvable kwarg is deprecated, use kwarg `solvableFilter = (>=solvable)` instead", #v0.29 - :listNeighbors, + :listNeighborhood, ) !isnothing(solvableFilter) && error("Cannot use both solvable and solvableFilter kwargs.") diff --git a/src/services/AbstractDFG.jl b/src/services/AbstractDFG.jl index 1ebdec72..42584404 100644 --- a/src/services/AbstractDFG.jl +++ b/src/services/AbstractDFG.jl @@ -346,7 +346,7 @@ Implement `listNeighbors(dfg::AbstractDFG, label::Symbol; solvableFilter, tagsFi function listNeighbors end function listNeighbors(dfg::AbstractDFG, node::AbstractGraphNode; kwargs...) - return listNeighbors(dfg, node.label; kwargs...) + return listNeighbors(dfg, getLabel(node); kwargs...) end ##------------------------------------------------------------------------------ ## copy and duplication @@ -587,7 +587,7 @@ Build a list of all unique neighbors inside 'distance'. Neighbors can be filtere Filters are applied to final neighborhood result. Notes -- Returns `Vector{Symbol}` +- Returns a tuple `(variableLabels, factorLabels)`, where each element is a `Vector{Symbol}`. Related: - [`copyGraph!`](@ref) @@ -663,7 +663,7 @@ function buildSubgraph( if !isnothing(solvable) Base.depwarn( "solvable kwarg is deprecated, use kwarg `solvableFilter = (>=solvable)` instead", #v0.29 - :listNeighbors, + :buildSubgraph, ) !isnothing(solvableFilter) && error("Cannot use both solvable and solvableFilter kwargs.")