Skip to content

Commit 186618d

Browse files
committed
WIP on cleanup and interface refactoring
1 parent c66e2b8 commit 186618d

File tree

9 files changed

+340
-69
lines changed

9 files changed

+340
-69
lines changed

src/GraphsDFG/services/GraphsDFG.jl

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -447,19 +447,14 @@ end
447447

448448
"""
449449
$(SIGNATURES)
450-
Get a deep subgraph copy from the DFG given a list of variables and factors.
451-
Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
452-
Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
453-
"""
454-
function getSubgraph(dfg::GraphsDFG, variableFactorLabels::Vector{Symbol}, includeOrphanFactors::Bool=false, addToDFG::GraphsDFG=GraphsDFG{AbstractParams}())::GraphsDFG
455-
for label in variableFactorLabels
456-
if !haskey(dfg.labelDict, label)
457-
error("Variable/factor with label '$(label)' does not exist in the factor graph")
458-
end
459-
end
460-
461-
_copyIntoGraph!(dfg, addToDFG, variableFactorLabels, includeOrphanFactors)
462-
return addToDFG
450+
Gets an empty and unique CloudGraphsDFG derived from an existing DFG.
451+
"""
452+
function _getDuplicatedEmptyDFG(dfg::GraphsDFG)::GraphsDFG
453+
newDfg = GraphsDFG{typeof(dfg.solverParams)}(;
454+
userId=dfg.userId, robotId=dfg.robotId, sessionId=dfg.sessionId,
455+
params=deepcopy(dfg.solverParams))
456+
newDfg.description ="(Copy of) $(dfg.description)"
457+
return newDfg
463458
end
464459

465460
"""

src/LightDFG/entities/LightDFG.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ Base.getproperty(x::LightDFG,f::Symbol) = begin
3737
@error "Depreciated? returning number of nodes"
3838
nv(x.g)
3939
elseif f == :labelDict
40-
@error "Depreciated? Concider using exists(dfg,label) instead. Returing internals copy"
40+
@error "Depreciated? Consider using exists(dfg,label) instead. Returning internals copy"
41+
#TODO: https://github.com/JuliaRobotics/DistributedFactorGraphs.jl/issues/111
4142
copy(x.g.labels.sym_int)
4243
else
4344
getfield(x,f)

src/services/AbstractDFG.jl

Lines changed: 324 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,327 @@ function getSerializationModule(dfg::G)::Module where G <: AbstractDFG
2525
return Main
2626
end
2727

28+
## Utility functions for getting type names and modules (from IncrementalInference)
29+
function _getmodule(t::T) where T
30+
T.name.module
31+
end
32+
function _getname(t::T) where T
33+
T.name.name
34+
end
35+
36+
## Interface for an AbstractDFG
37+
38+
"""
39+
$(SIGNATURES)
40+
True if the variable or factor exists in the graph.
41+
"""
42+
function exists(dfg::G, node::N) where {G <: AbstractDFG, N <: DFGNode}
43+
error("exists not implemented for $(typeof(dfg))")
44+
end
45+
46+
"""
47+
$(SIGNATURES)
48+
Add a DFGVariable to a DFG.
49+
"""
50+
function addVariable!(dfg::G, variable::DFGVariable)::Bool where G <: AbstractDFG
51+
error("addVariable! not implemented for $(typeof(dfg))")
52+
end
53+
54+
"""
55+
$(SIGNATURES)
56+
Add a DFGFactor to a DFG.
57+
"""
58+
function addFactor!(dfg::G, variables::Vector{DFGVariable}, factor::DFGFactor)::Bool where G <: AbstractDFG
59+
error("addFactor! not implemented for $(typeof(dfg))")
60+
end
61+
62+
"""
63+
$(SIGNATURES)
64+
Add a DFGFactor to a DFG.
65+
"""
66+
function addFactor!(dfg::G, variableIds::Vector{Symbol}, factor::DFGFactor)::Bool where G <: AbstractDFG
67+
error("addFactor! not implemented for $(typeof(dfg))")
68+
end
69+
70+
"""
71+
$(SIGNATURES)
72+
Get a DFGVariable from a DFG using its underlying integer ID.
73+
"""
74+
function getVariable(dfg::G, variableId::Int64)::DFGVariable where G <: AbstractDFG
75+
error("getVariable not implemented for $(typeof(dfg))")
76+
end
77+
78+
"""
79+
$(SIGNATURES)
80+
Get a DFGVariable from a DFG using its label.
81+
"""
82+
function getVariable(dfg::G, label::Union{Symbol, String})::DFGVariable where G <: AbstractDFG
83+
error("getVariable not implemented for $(typeof(dfg))")
84+
end
85+
86+
"""
87+
$(SIGNATURES)
88+
Get a DFGFactor from a DFG using its underlying integer ID.
89+
"""
90+
function getFactor(dfg::G, factorId::Int64)::DFGFactor where G <: AbstractDFG
91+
error("getFactor not implemented for $(typeof(dfg))")
92+
end
93+
94+
"""
95+
$(SIGNATURES)
96+
Get a DFGFactor from a DFG using its label.
97+
"""
98+
function getFactor(dfg::G, label::Union{Symbol, String})::DFGFactor where G <: AbstractDFG
99+
error("getFactor not implemented for $(typeof(dfg))")
100+
end
101+
102+
"""
103+
$(SIGNATURES)
104+
Update a complete DFGVariable in the DFG.
105+
"""
106+
function updateVariable!(dfg::G, variable::DFGVariable)::DFGVariable where G <: AbstractDFG
107+
error("updateVariable! not implemented for $(typeof(dfg))")
108+
end
109+
110+
"""
111+
$(SIGNATURES)
112+
Update a complete DFGFactor in the DFG.
113+
"""
114+
function updateFactor!(dfg::G, factor::DFGFactor)::DFGFactor where G <: AbstractDFG
115+
error("updateFactor! not implemented for $(typeof(dfg))")
116+
end
117+
118+
"""
119+
$(SIGNATURES)
120+
Delete a DFGVariable from the DFG using its label.
121+
"""
122+
function deleteVariable!(dfg::G, label::Symbol)::DFGVariable where G <: AbstractDFG
123+
error("deleteVariable! not implemented for $(typeof(dfg))")
124+
end
125+
126+
#Alias
127+
"""
128+
$(SIGNATURES)
129+
Delete a referenced DFGVariable from the DFG.
130+
"""
131+
function deleteVariable!(dfg::G, variable::DFGVariable)::DFGVariable where G <: AbstractDFG
132+
return deleteVariable!(dfg, variable.label)
133+
end
134+
135+
"""
136+
$(SIGNATURES)
137+
Delete a DFGFactor from the DFG using its label.
138+
"""
139+
function deleteFactor!(dfg::G, label::Symbol)::DFGFactor where G <: AbstractDFG
140+
error("deleteFactors not implemented for $(typeof(dfg))")
141+
end
142+
143+
# Alias
144+
"""
145+
$(SIGNATURES)
146+
Delete the referened DFGFactor from the DFG.
147+
"""
148+
function deleteFactor!(dfg::G, factor::DFGFactor)::DFGFactor where G <: AbstractDFG
149+
return deleteFactor!(dfg, factor.label)
150+
end
151+
152+
"""
153+
$(SIGNATURES)
154+
List the DFGVariables in the DFG.
155+
Optionally specify a label regular expression to retrieves a subset of the variables.
156+
"""
157+
function getVariables(dfg::G, regexFilter::Union{Nothing, Regex}=nothing; tags::Vector{Symbol}=Symbol[])::Vector{DFGVariable} where G <: AbstractDFG
158+
error("getVariables not implemented for $(typeof(dfg))")
159+
end
160+
161+
"""
162+
$(SIGNATURES)
163+
Get a list of IDs of the DFGVariables in the DFG.
164+
Optionally specify a label regular expression to retrieves a subset of the variables.
165+
166+
Example
167+
```julia
168+
getVariableIds(dfg, r"l", tags=[:APRILTAG;])
169+
```
170+
171+
Related
172+
173+
ls
174+
"""
175+
function getVariableIds(dfg::G, regexFilter::Union{Nothing, Regex}=nothing; tags::Vector{Symbol}=Symbol[])::Vector{Symbol} where G <: AbstractDFG
176+
vars = getVariables(dfg, regexFilter, tags=tags)
177+
# mask = map(v -> length(intersect(v.tags, tags)) > 0, vars )
178+
return map(v -> v.label, vars)
179+
end
180+
181+
# Alias
182+
"""
183+
$(SIGNATURES)
184+
List the DFGVariables in the DFG.
185+
Optionally specify a label regular expression to retrieves a subset of the variables.
186+
"""
187+
function ls(dfg::G, regexFilter::Union{Nothing, Regex}=nothing; tags::Vector{Symbol}=Symbol[])::Vector{Symbol} where G <: AbstractDFG
188+
return getVariableIds(dfg, regexFilter, tags=tags)
189+
end
190+
191+
"""
192+
$(SIGNATURES)
193+
List the DFGFactors in the DFG.
194+
Optionally specify a label regular expression to retrieves a subset of the factors.
195+
"""
196+
function getFactors(dfg::G, regexFilter::Union{Nothing, Regex}=nothing)::Vector{DFGFactor} where G <: AbstractDFG
197+
error("getFactors not implemented for $(typeof(dfg))")
198+
end
199+
200+
"""
201+
$(SIGNATURES)
202+
Get a list of the IDs of the DFGFactors in the DFG.
203+
Optionally specify a label regular expression to retrieves a subset of the factors.
204+
"""
205+
function getFactorIds(dfg::G, regexFilter::Union{Nothing, Regex}=nothing)::Vector{Symbol} where G <: AbstractDFG
206+
return map(f -> f.label, getFactors(dfg, regexFilter))
207+
end
208+
209+
"""
210+
$(SIGNATURES)
211+
List the DFGFactors in the DFG.
212+
Optionally specify a label regular expression to retrieves a subset of the factors.
213+
"""
214+
# Alias
215+
function lsf(dfg::G, regexFilter::Union{Nothing, Regex}=nothing)::Vector{Symbol} where G <: AbstractDFG
216+
return getFactorIds(dfg, regexFilter)
217+
end
218+
219+
"""
220+
$(SIGNATURES)
221+
Alias for getNeighbors - returns neighbors around a given node label.
222+
"""
223+
function lsf(dfg::G, label::Symbol)::Vector{Symbol} where G <: AbstractDFG
224+
return getNeighbors(dfg, label)
225+
end
226+
227+
"""
228+
$(SIGNATURES)
229+
Checks if the graph is fully connected, returns true if so.
230+
"""
231+
function isFullyConnected(dfg::G)::Bool where G <: AbstractDFG
232+
error("isFullyConnected not implemented for $(typeof(dfg))")
233+
end
234+
235+
#Alias
236+
"""
237+
$(SIGNATURES)
238+
Checks if the graph is not fully connected, returns true if it is not contiguous.
239+
"""
240+
function hasOrphans(dfg::G)::Bool where G <: AbstractDFG
241+
return !isFullyConnected(dfg)
242+
end
243+
244+
"""
245+
$(SIGNATURES)
246+
Retrieve a list of labels of the immediate neighbors around a given variable or factor.
247+
"""
248+
function getNeighbors(dfg::G, node::T; ready::Union{Nothing, Int}=nothing, backendset::Union{Nothing, Int}=nothing)::Vector{Symbol} where {G <: AbstractDFG, T <: DFGNode}
249+
error("getNeighbors not implemented for $(typeof(dfg))")
250+
end
251+
"""
252+
$(SIGNATURES)
253+
Retrieve a list of labels of the immediate neighbors around a given variable or factor specified by its label.
254+
"""
255+
function getNeighbors(dfg::G, label::Symbol; ready::Union{Nothing, Int}=nothing, backendset::Union{Nothing, Int}=nothing)::Vector{Symbol} where G <: AbstractDFG
256+
error("getNeighbors not implemented for $(typeof(dfg))")
257+
end
258+
259+
# Aliases
260+
"""
261+
$(SIGNATURES)
262+
Retrieve a list of labels of the immediate neighbors around a given variable or factor.
263+
"""
264+
function ls(dfg::G, node::T)::Vector{Symbol} where {G <: AbstractDFG, T <: DFGNode}
265+
return getNeighbors(dfg, node)
266+
end
267+
"""
268+
$(SIGNATURES)
269+
Retrieve a list of labels of the immediate neighbors around a given variable or factor specified by its label.
270+
"""
271+
function ls(dfg::G, label::Symbol)::Vector{Symbol} where G <: AbstractDFG
272+
return getNeighbors(dfg, label)
273+
end
274+
275+
"""
276+
$(SIGNATURES)
277+
Gets an empty and unique CloudGraphsDFG derived from an existing DFG.
278+
"""
279+
function _getDuplicatedEmptyDFG(dfg::G)::G where G <: AbstractDFG
280+
error("_getDuplicatedEmptyDFG not implemented for $(typeof(dfg))")
281+
end
282+
283+
# TODO: NEED TO FIGURE OUT SIGNATURE FOR DEFAULT ARGS
284+
285+
"""
286+
$(SIGNATURES)
287+
Retrieve a deep subgraph copy around a given variable or factor.
288+
Optionally provide a distance to specify the number of edges should be followed.
289+
Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
290+
Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
291+
"""
292+
function getSubgraphAroundNode(dfg::G, node::T, distance::Int64=1, includeOrphanFactors::Bool=false, addToDFG::H=_getDuplicatedEmptyDFG(dfg))::G where {G <: AbstractDFG, H <: AbstractDFG, P <: AbstractParams, T <: DFGNode}
293+
error("getSubgraphAroundNode not implemented for $(typeof(dfg))")
294+
end
295+
296+
"""
297+
$(SIGNATURES)
298+
Get a deep subgraph copy from the DFG given a list of variables and factors.
299+
Optionally provide an existing subgraph addToDFG, the extracted nodes will be copied into this graph. By default a new subgraph will be created.
300+
Note: By default orphaned factors (where the subgraph does not contain all the related variables) are not returned. Set includeOrphanFactors to return the orphans irrespective of whether the subgraph contains all the variables.
301+
"""
302+
function getSubgraph(dfg::G,
303+
variableFactorLabels::Vector{Symbol},
304+
includeOrphanFactors::Bool=false,
305+
addToDFG::H=_getDuplicatedEmptyDFG(dfg))::H where {G <: AbstractDFG, H <: AbstractDFG}
306+
for label in variableFactorLabels
307+
if !exists(dfg, label)
308+
error("Variable/factor with label '$(label)' does not exist in the factor graph")
309+
end
310+
end
311+
312+
_copyIntoGraph!(dfg, addToDFG, variableFactorLabels, includeOrphanFactors)
313+
return addToDFG
314+
end
315+
316+
"""
317+
$(SIGNATURES)
318+
Get an adjacency matrix for the DFG, returned as a Matrix{Union{Nothing, Symbol}}.
319+
Rows are all factors, columns are all variables, and each cell contains either nothing or the symbol of the relating factor.
320+
The first row and first column are factor and variable headings respectively.
321+
"""
322+
function getAdjacencyMatrix(dfg::G)::Matrix{Union{Nothing, Symbol}} where G <: AbstractDFG
323+
error("getAdjacencyMatrix not implemented for $(typeof(dfg))")
324+
end
325+
326+
"""
327+
$(SIGNATURES)
328+
Produces a dot-format of the graph for visualization.
329+
"""
330+
function toDot(dfg::G)::String where G <: AbstractDFG
331+
error("toDot not implemented for $(typeof(dfg))")
332+
end
333+
334+
"""
335+
$(SIGNATURES)
336+
Produces a dot file of the graph for visualization.
337+
Download XDot to see the data
338+
339+
Note
340+
- Default location "/tmp/dfg.dot" -- MIGHT BE REMOVED
341+
- Can be viewed with the `xdot` system application.
342+
- Based on graphviz.org
343+
"""
344+
function toDotFile(dfg::G, fileName::String="/tmp/dfg.dot")::Nothing where G <: AbstractDFG
345+
error("toDotFile not implemented for $(typeof(dfg))")
346+
end
347+
348+
28349
"""
29350
$(SIGNATURES)
30351
Common function for copying nodes from one graph into another graph.
@@ -67,18 +388,11 @@ function _copyIntoGraph!(sourceDFG::G, destDFG::H, variableFactorLabels::Vector{
67388
return nothing
68389
end
69390

70-
## Utility functions for getting type names and modules (from IncrementalInference)
71-
function _getmodule(t::T) where T
72-
T.name.module
73-
end
74-
function _getname(t::T) where T
75-
T.name.name
76-
end
77-
78-
## Interfaces
79391
"""
80392
$(SIGNATURES)
81393
Get an adjacency matrix for the DFG, returned as a tuple: adjmat::SparseMatrixCSC{Int}, var_labels::Vector{Symbol) fac_labels::Vector{Symbol).
82394
Rows are the factors, columns are the variables, with the corresponding labels in fac_labels,var_labels.
83395
"""
84-
getAdjacencyMatrixSparse(dfg::AbstractDFG) = error("getAdjacencyMatrixSparse not implemented for $(typeof(dfg))")
396+
function getAdjacencyMatrixSparse(dfg::G) where G <: AbstractDFG
397+
error("getAdjacencyMatrixSparse not implemented for $(typeof(dfg))")
398+
end

0 commit comments

Comments
 (0)