Skip to content

Commit 33d6f18

Browse files
committed
Merge branch 'master' into enhancement/2Q20/nodelabelvalidation
2 parents d910991 + 1605f07 commit 33d6f18

File tree

17 files changed

+185
-73
lines changed

17 files changed

+185
-73
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "DistributedFactorGraphs"
22
uuid = "b5cc3c7e-6572-11e9-2517-99fb8daf2f04"
3-
version = "0.7.5"
3+
version = "0.8.0"
44

55
[deps]
66
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

src/BigData/services/AbstractBigDataEntries.jl

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ addDataEntry!(x...) = addBigDataEntry!(x...)
4141
$(SIGNATURES)
4242
Add Big Data Entry to distributed factor graph.
4343
Should be extended if DFG variable is not returned by reference.
44+
45+
Example
46+
47+
See docs for `getDataEntryElement`.
48+
49+
Related
50+
51+
addData!, getDataEntryElement, fetchData
4452
"""
4553
function addDataEntry!(dfg::AbstractDFG,
4654
lbl::Symbol,
@@ -51,12 +59,13 @@ function addDataEntry!(dfg::AbstractDFG,
5159
#
5260
node = isVariable(dfg, lbl) ? getVariable(dfg, lbl) : getFactor(dfg, lbl)
5361
# Make a big data entry in the graph - use JSON2 to just write this
54-
element = GeneralBigDataEntry(dfg, node, descr, mimeType=mimeType)
62+
entry = GeneralBigDataEntry(dfg, node, descr, mimeType=mimeType)
5563
# Set it in the store
56-
addBigData!(datastore, element, data)
64+
addBigData!(datastore, entry, data)
5765
# Add the entry to the graph
58-
addBigDataEntry!(node, element)
66+
addBigDataEntry!(node, entry)
5967
end
68+
const addData! = addDataEntry!
6069

6170
"""
6271
$SIGNATURES
@@ -79,9 +88,68 @@ function getBigDataEntry(dfg::AbstractDFG, label::Symbol, key::Symbol)
7988
return getBigDataEntry(getVariable(dfg, label), key)
8089
end
8190

91+
"""
92+
$SIGNATURES
93+
Get both the entry and raw data element from datastore returning as a tuple.
94+
95+
Notes:
96+
- This is the counterpart to `addDataEntry!`.
97+
- Data is identified by the node in the DFG object `dfglabel::Symbol` as well as `datalabel::Symbol`.
98+
- The data should have been stored along with a `entry.mimeType::String` which describes the format of the data.
99+
- ImageMagick.jl is useful for storing images in png or jpg compressed format.
100+
101+
Example
102+
103+
```julia
104+
# some dfg object
105+
fg = initfg()
106+
addVariable!(fg, :x0, IIF.ContinuousScalar) # using IncrementalInference
107+
# FileDataStore (as example)
108+
datastore = FileDataStore(joinLogPath(fg,"datastore"))
109+
110+
# now some data comes in
111+
mydata = Dict(:soundBite => randn(Float32, 10000), :meta => "something about lazy foxes and fences.")
112+
113+
# store the data
114+
addDataEntry!( fg, :x0, datastore, :SOUND_DATA, "application/json", Vector{UInt8}(JSON2.write( mydata )) )
115+
116+
# get/fetch the data
117+
entry, rawData = fetchData(fg, :x0, datastore, :SOUND_DATA)
118+
119+
# unpack data to original format (this must be done by the user)
120+
@show entry.mimeType # "applicatio/json"
121+
userFormat = JSON2.read(IOBuffer(rawData))
122+
```
123+
124+
Related
125+
126+
addDataEntry!, addData!, fetchData, fetchDataEntryElement
127+
"""
128+
function getDataEntryElement(dfg::AbstractDFG,
129+
dfglabel::Symbol,
130+
datastore::Union{FileDataStore, InMemoryDataStore},
131+
datalabel::Symbol)
132+
#
133+
vari = getVariable(dfg, dfglabel)
134+
if !hasDataEntry(vari, datalabel)
135+
@error "missing data entry $datalabel in $dfglabel"
136+
return nothing, nothing
137+
end
138+
entry = getBigDataEntry(vari, datalabel)
139+
element = getBigData(datastore, entry)
140+
return entry, element
141+
end
142+
const fetchDataEntryElement = getDataEntryElement
143+
const fetchData = getDataEntryElement
144+
145+
146+
82147
"""
83148
$(SIGNATURES)
84149
Update big data entry
150+
151+
DevNote
152+
- DF, unclear if `update` verb is applicable in this case, see #404
85153
"""
86154
function updateBigDataEntry!(var::AbstractDFGVariable, bde::AbstractBigDataEntry)
87155
!haskey(var.bigData,bde.key) && (@warn "$(bde.key) does not exist in variable, adding")

src/CloudGraphsDFG/services/CloudGraphsDFG.jl

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,27 @@ function updateFactor!(dfg::CloudGraphsDFG, factor::DFGFactor)::DFGFactor
304304
return factor
305305
end
306306

307-
function deleteVariable!(dfg::CloudGraphsDFG, label::Symbol)::DFGVariable
307+
function deleteVariable!(dfg::CloudGraphsDFG, label::Symbol)#::Tuple{AbstractDFGVariable, Vector{<:AbstractDFGFactor}}
308308
variable = getVariable(dfg, label)
309309
if variable == nothing
310310
error("Unable to retrieve the ID for variable '$label'. Please check your connection to the database and that the variable exists.")
311311
end
312312

313+
deleteNeighbors = true # reserved, orphaned factors are not supported at this time
314+
if deleteNeighbors
315+
neigfacs = map(l->deleteFactor!(dfg, l), getNeighbors(dfg, label))
316+
end
317+
313318
# Perform detach+deletion
314319
_getNeoNodesFromCyphonQuery(dfg.neo4jInstance, "(node:$label:$(join(_getLabelsForType(dfg, DFGVariable),':'))) detach delete node ")
315320

316321
# Clearing history
317322
dfg.addHistory = symdiff(dfg.addHistory, [label])
318-
return variable
323+
return variable, neigfacs
319324
end
320325

321326
#Alias
322-
deleteVariable!(dfg::CloudGraphsDFG, variable::DFGVariable)::DFGVariable = deleteVariable!(dfg, variable.label)
327+
deleteVariable!(dfg::CloudGraphsDFG, variable::DFGVariable) = deleteVariable!(dfg, variable.label)
323328

324329
function deleteFactor!(dfg::CloudGraphsDFG, label::Symbol)::DFGFactor
325330
factor = getFactor(dfg, label)
@@ -375,7 +380,7 @@ function listFactors(dfg::CloudGraphsDFG, regexFilter::Union{Nothing, Regex}=not
375380
end
376381
end
377382

378-
function isFullyConnected(dfg::CloudGraphsDFG)::Bool
383+
function isConnected(dfg::CloudGraphsDFG)::Bool
379384
# If the total number of nodes == total number of distinct connected nodes, then it is fully connected
380385
# Total nodes
381386
varIds = listVariables(dfg)
@@ -397,7 +402,7 @@ function isFullyConnected(dfg::CloudGraphsDFG)::Bool
397402
end
398403

399404
function getNeighbors(dfg::CloudGraphsDFG, node::T; solvable::Int=0)::Vector{Symbol} where T <: DFGNode
400-
query = "(n:$(dfg.userId):$(dfg.robotId):$(dfg.sessionId):$(node.label))--(node) where (node:VARIABLE or node:FACTOR) and node.solvable >= $solvable"
405+
query = "(n:$(dfg.userId):$(dfg.robotId):$(dfg.sessionId):$(node.label))-[r:FACTORGRAPH]-(node) where (node:VARIABLE or node:FACTOR) and node.solvable >= $solvable"
401406
@debug "[Query] $query"
402407
neighbors = _getLabelsFromCyphonQuery(dfg.neo4jInstance, query)
403408
# If factor, need to do variable ordering TODO, Do we? does it matter if we always use _variableOrderSymbols in calculations?
@@ -408,7 +413,7 @@ function getNeighbors(dfg::CloudGraphsDFG, node::T; solvable::Int=0)::Vector{Sym
408413
end
409414

410415
function getNeighbors(dfg::CloudGraphsDFG, label::Symbol; solvable::Int=0)::Vector{Symbol}
411-
query = "(n:$(dfg.userId):$(dfg.robotId):$(dfg.sessionId):$(label))--(node) where (node:VARIABLE or node:FACTOR) and node.solvable >= $solvable"
416+
query = "(n:$(dfg.userId):$(dfg.robotId):$(dfg.sessionId):$(label))-[r:FACTORGRAPH]-(node) where (node:VARIABLE or node:FACTOR) and node.solvable >= $solvable"
412417
@debug "[Query] $query"
413418
neighbors = _getLabelsFromCyphonQuery(dfg.neo4jInstance, query)
414419
# If factor, need to do variable ordering TODO, Do we? does it matter if we always use _variableOrderSymbols in calculations?

src/Deprecated.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ function Base.convert(::Type{SkeletonDFGFactor}, f::FactorDataLevel1)
106106
return SkeletonDFGFactor(f)
107107
end
108108

109+
110+
@deprecate hasOrphans(dfg) !isConnected(dfg)
111+
@deprecate isFullyConnected(dfg) isConnected(dfg)
112+
109113
##==============================================================================
110114
## WIP on consolidated subgraph functions, aim to remove in 0.8
111115
##==============================================================================

src/DistributedFactorGraphs.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export exists,
7171
getVariables, getFactors,
7272
isVariable, isFactor
7373

74-
export isFullyConnected, hasOrphans
74+
export isConnected
7575

7676
export getBiadjacencyMatrix
7777

@@ -165,15 +165,19 @@ export getNeighborhood, getNeighbors, _getDuplicatedEmptyDFG
165165
export copyGraph!, deepcopyGraph, deepcopyGraph!, buildSubgraph, mergeGraph!
166166
# Big Data
167167
##------------------------------------------------------------------------------
168-
export addBigDataEntry!, addDataEntry!, getBigDataEntry, updateBigDataEntry!, deleteBigDataEntry!, getBigDataEntries, getBigDataKeys, hasDataEntry, hasBigDataEntry
168+
export addBigDataEntry!, getBigDataEntry, updateBigDataEntry!, deleteBigDataEntry!, getBigDataEntries, getBigDataKeys, hasDataEntry, hasBigDataEntry
169+
# convenience wrappers
170+
export addDataEntry!, getDataEntryElement
171+
# aliases
172+
export addData!, fetchData, fetchDataEntryElement
169173

170174

171175
##------------------------------------------------------------------------------
172176
# Factors
173177
##------------------------------------------------------------------------------
174178
# Factor Data
175179
export GenericFunctionNodeData
176-
export InferenceType, PackedInferenceType, FunctorInferenceType, ConvolutionObject
180+
export InferenceType, PackedInferenceType, FunctorInferenceType, FactorOperationalMemory
177181
export FunctorSingleton, FunctorPairwise, FunctorPairwiseMinimize
178182

179183
# accessors
@@ -228,7 +232,8 @@ export
228232

229233

230234
## Deprecated exports should be listed in Deprecated.jl if possible, otherwise here
231-
235+
#TODO remove export in DFG v0.8.0
236+
export ConvolutionObject
232237

233238
## needsahome.jl
234239
import Base: print

src/GraphsDFG/GraphsDFG.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ import ...DistributedFactorGraphs: setSolverParams!,
3636
getFactors,
3737
listFactors,
3838
lsf,
39-
isFullyConnected,
40-
hasOrphans,
39+
isConnected,
4140
getNeighbors,
4241
buildSubgraph,
4342
copyGraph!,

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,21 @@ function updateFactor!(dfg::GraphsDFG, factor::DFGFactor)::DFGFactor
165165
return factor
166166
end
167167

168-
function deleteVariable!(dfg::GraphsDFG, label::Symbol)::DFGVariable
168+
function deleteVariable!(dfg::GraphsDFG, label::Symbol)#::Tuple{AbstractDFGVariable, Vector{<:AbstractDFGFactor}}
169169
if !haskey(dfg.labelDict, label)
170170
error("Variable label '$(label)' does not exist in the factor graph")
171171
end
172+
173+
deleteNeighbors = true # reserved, orphaned factors are not supported at this time
174+
if deleteNeighbors
175+
neigfacs = map(l->deleteFactor!(dfg, l), getNeighbors(dfg, label))
176+
end
177+
178+
172179
variable = dfg.g.vertices[dfg.labelDict[label]].dfgNode
173180
delete_vertex!(dfg.g.vertices[dfg.labelDict[label]], dfg.g)
174181
delete!(dfg.labelDict, label)
175-
return variable
182+
return variable, neigfacs
176183
end
177184

178185
function deleteFactor!(dfg::GraphsDFG, label::Symbol)::DFGFactor
@@ -220,7 +227,7 @@ function getFactors(dfg::GraphsDFG, regexFilter::Union{Nothing, Regex}=nothing;
220227
return factors
221228
end
222229

223-
function isFullyConnected(dfg::GraphsDFG)::Bool
230+
function isConnected(dfg::GraphsDFG)::Bool
224231
return length(Graphs.connected_components(dfg.g)) == 1
225232
end
226233

src/LightDFG/LightDFG.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ import ...DistributedFactorGraphs: setSolverParams!,
3838
getFactors,
3939
listFactors,
4040
lsf,
41-
isFullyConnected,
42-
hasOrphans,
41+
isConnected,
4342
getNeighbors,
4443
buildSubgraph,
4544
copyGraph!,

src/LightDFG/services/LightDFG.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,19 @@ function updateFactor!(dfg::LightDFG, factor::F)::F where F <: AbstractDFGFactor
130130
return factor
131131
end
132132

133-
function deleteVariable!(dfg::LightDFG, label::Symbol)::AbstractDFGVariable
133+
function deleteVariable!(dfg::LightDFG, label::Symbol)#::Tuple{AbstractDFGVariable, Vector{<:AbstractDFGFactor}}
134134
if !haskey(dfg.g.variables, label)
135135
error("Variable label '$(label)' does not exist in the factor graph")
136136
end
137+
138+
deleteNeighbors = true # reserved, orphaned factors are not supported at this time
139+
if deleteNeighbors
140+
neigfacs = map(l->deleteFactor!(dfg, l), getNeighbors(dfg, label))
141+
end
137142
variable = dfg.g.variables[label]
138143
rem_vertex!(dfg.g, dfg.g.labels[label])
139144

140-
return variable
145+
return variable, neigfacs
141146
end
142147

143148
function deleteFactor!(dfg::LightDFG, label::Symbol)::AbstractDFGFactor
@@ -210,8 +215,9 @@ function listFactors(dfg::LightDFG, regexFilter::Union{Nothing, Regex}=nothing;
210215
return factors
211216
end
212217

213-
function isFullyConnected(dfg::LightDFG)::Bool
214-
return length(LightGraphs.connected_components(dfg.g)) == 1
218+
function isConnected(dfg::LightDFG)::Bool
219+
return LightGraphs.is_connected(dfg.g)
220+
# return length(LightGraphs.connected_components(dfg.g)) == 1
215221
end
216222

217223
function _isSolvable(dfg::LightDFG, label::Symbol, ready::Int)::Bool

src/entities/DFGFactor.jl

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@ abstract type PackedInferenceType end
77

88
abstract type FunctorInferenceType <: Function end
99

10-
# DF suggestion1 (this is a first guess) `ConvolutionObject` --> `FactorInsituObject`
11-
# DF second guess, ConvolutionObject <: FactorInsituObject
12-
# JT Maybe second guess as intermediate step where ConvolutionObject is moved to IIF.
13-
# then it can be removed to CommonConvWrapper <: FactorInsituObject
14-
15-
# DF, Convolution is IIF idea, but DFG should know about "FactorOperationalMemory"
16-
# DF, IIF.CommonConvWrapper <: FactorOperationalMemory # FIXME
17-
# MAYBE rename "FactorOperationalMemory"
18-
abstract type ConvolutionObject <: Function end
10+
# NOTE DF, Convolution is IIF idea, but DFG should know about "FactorOperationalMemory"
11+
# DF, IIF.CommonConvWrapper <: FactorOperationalMemory #
12+
abstract type FactorOperationalMemory <: Function end
13+
# TODO to be removed from DFG,
14+
# we can add to IIF or have IIF.CommonConvWrapper <: FactorOperationalMemory directly
15+
abstract type ConvolutionObject <: FactorOperationalMemory end
1916

2017
abstract type FunctorSingleton <: FunctorInferenceType end
2118
abstract type FunctorPairwise <: FunctorInferenceType end
@@ -37,7 +34,7 @@ Designing (WIP)
3734
# in IIF.FunctorPairwiseMinimize <: InferenceType # DFG whatever, something, we'll figure it out
3835
# in Main/User, SomeFactor <: FunctorPairwiseMinimize
3936
"""
40-
mutable struct GenericFunctionNodeData{T, S} #{T<:Union{PackedInferenceType, FunctorInferenceType, ConvolutionObject}, S<:Union{Symbol, AbstractString}}
37+
mutable struct GenericFunctionNodeData{T, S} #{T<:Union{PackedInferenceType, FunctorInferenceType, FactorOperationalMemory}, S<:Union{Symbol, AbstractString}}
4138
fncargvID::Vector{Symbol}
4239
eliminated::Bool
4340
potentialused::Bool
@@ -62,7 +59,7 @@ end
6259
const PackedFunctionNodeData{T} = GenericFunctionNodeData{T, <: AbstractString}
6360
PackedFunctionNodeData(x1, x2, x3, x4, x5::S, x6::T, multihypo::Vector{Float64}=[], certainhypo::Vector{Int}=Int[], x9::Int=0) where {T <: PackedInferenceType, S <: AbstractString} = GenericFunctionNodeData(x1, x2, x3, x4, x5, x6, multihypo, certainhypo, x9)
6461
const FunctionNodeData{T} = GenericFunctionNodeData{T, Symbol}
65-
FunctionNodeData(x1, x2, x3, x4, x5::Symbol, x6::T, multihypo::Vector{Float64}=[], certainhypo::Vector{Int}=Int[], x9::Int=0) where {T <: Union{FunctorInferenceType, ConvolutionObject}}= GenericFunctionNodeData{T, Symbol}(x1, x2, x3, x4, x5, x6, multihypo, certainhypo, x9)
62+
FunctionNodeData(x1, x2, x3, x4, x5::Symbol, x6::T, multihypo::Vector{Float64}=[], certainhypo::Vector{Int}=Int[], x9::Int=0) where {T <: Union{FunctorInferenceType, FactorOperationalMemory}}= GenericFunctionNodeData{T, Symbol}(x1, x2, x3, x4, x5, x6, multihypo, certainhypo, x9)
6663

6764
##==============================================================================
6865
## Factors
@@ -104,7 +101,7 @@ mutable struct DFGFactor{T, S} <: AbstractDFGFactor
104101
"""Mutable parameters for the variable. We suggest using accessors to get to this data.
105102
Accessors: [`getSolvable`](@ref), [`setSolvable!`](@ref)"""
106103
_dfgNodeParams::DFGNodeParams
107-
"""Internal cache of the ordering of the neighbor variables. Rather use getNeighbors to get the list as this is an internal value.
104+
"""Internal cache of the ordering of the neighbor variables. Rather use getVariableOrder to get the list as this is an internal value.
108105
Accessors: [`getVariableOrder`](@ref)"""
109106
_variableOrderSymbols::Vector{Symbol}
110107
end

0 commit comments

Comments
 (0)