|
| 1 | +# Factor Graph OS type utilities |
| 2 | +# IIF methods should direclty detect extended types from user import |
| 3 | +# of convert in their namespace |
| 4 | + |
| 5 | + |
| 6 | +function convert{PT <: PackedInferenceType, T <:FunctorInferenceType}(::Type{PT}, ::T) |
| 7 | + getfield(T.name.module, Symbol("Packed$(T.name.name)")) |
| 8 | +end |
| 9 | +function convert{T <: FunctorInferenceType, PT <: PackedInferenceType}(::Type{T}, ::PT) |
| 10 | + getfield(PT.name.module, Symbol(string(PT.name.name)[7:end])) |
| 11 | +end |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +""" |
| 16 | + convert2packedfunctionnode(fgl::FactorGraph, fsym::Symbol) |
| 17 | +
|
| 18 | +Encode complicated function node type with assumed to exist, user supplied convert |
| 19 | +function to related 'Packed<type>' format. |
| 20 | +""" |
| 21 | +function convert2packedfunctionnode(fgl::FactorGraph, |
| 22 | + fsym::Symbol, |
| 23 | + api::DataLayerAPI=localapi ) |
| 24 | + # |
| 25 | + fid = fgl.fIDs[fsym] |
| 26 | + fnc = getfnctype(fgl, fid) |
| 27 | + usrtyp = convert(PackedInferenceType, fnc) |
| 28 | + cfnd = convert(PackedFunctionNodeData{usrtyp},getData(fgl, fid, api=api) ) |
| 29 | + return cfnd, usrtyp |
| 30 | +end |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | +""" |
| 36 | + encodefg(fgl::FactorGraph) |
| 37 | +
|
| 38 | +Make a full memory copy of the graph and encode all complicated function node |
| 39 | +types with assumed to exist convert to 'Packed<type>' formats. Same converters |
| 40 | +as used for database persistence storage with CloudGraphs.jl. |
| 41 | +""" |
| 42 | +function encodefg(fgl::FactorGraph; |
| 43 | + api::DataLayerAPI=localapi ) |
| 44 | + # |
| 45 | + fgs = deepcopy(fgl) |
| 46 | + fgs.cg = nothing |
| 47 | + fgs.registeredModuleFunctions = nothing |
| 48 | + fgs.g = Graphs.incdict(Graphs.ExVertex,is_directed=false) |
| 49 | + @showprogress 1 "Encoding variables..." for (vsym,vid) in fgl.IDs |
| 50 | + cpvert = deepcopy(getVert(fgl, vid, api=api)) |
| 51 | + api.addvertex!(fgs, cpvert) #, labels=vnlbls) # currently losing labels |
| 52 | + end |
| 53 | + |
| 54 | + @showprogress 1 "Encoding factors..." for (fsym,fid) in fgs.fIDs |
| 55 | + data,ftyp = convert2packedfunctionnode(fgl, fsym) |
| 56 | + # data = FunctionNodeData{ftyp}(Int[], false, false, Int[], m, gwpf) |
| 57 | + newvert = ExVertex(fid,string(fsym)) |
| 58 | + for (key,val) in getVert(fgl,fid,api=api).attributes |
| 59 | + newvert.attributes[key] = val |
| 60 | + end |
| 61 | + setData!(newvert, data) |
| 62 | + api.addvertex!(fgs, newvert) |
| 63 | + end |
| 64 | + fgs.g.inclist = typeof(fgl.g.inclist)() |
| 65 | + |
| 66 | + # iterated over all edges |
| 67 | + @showprogress 1 "Encoding edges..." for (eid, edges) in fgl.g.inclist |
| 68 | + fgs.g.inclist[eid] = Vector{typeof(edges[1])}() |
| 69 | + for ed in edges |
| 70 | + newed = Graphs.Edge(ed.index, |
| 71 | + fgs.g.vertices[ed.source.index], |
| 72 | + fgs.g.vertices[ed.target.index] ) |
| 73 | + push!(fgs.g.inclist[eid], newed) |
| 74 | + end |
| 75 | + end |
| 76 | + |
| 77 | + return fgs |
| 78 | +end |
| 79 | + |
| 80 | +""" |
| 81 | + savefgjld(fgl::FactorGraph; file::AbstractString="tempfg.jld") |
| 82 | +
|
| 83 | +Save mostly complete Factor Graph type by converting complicated FunctionNodeData |
| 84 | +types to 'Packed' types using user supplied converters. Ground truth can also be |
| 85 | +saved and recovered by the associated loadjld(file="tempfg.jld") method. |
| 86 | +""" |
| 87 | +function savejld(fgl::FactorGraph; |
| 88 | + file::AbstractString="tempfg.jld", |
| 89 | + groundtruth=nothing) |
| 90 | + fgs = encodefg(fgl) |
| 91 | + if groundtruth == nothing |
| 92 | + @save file fgs |
| 93 | + else |
| 94 | + @save file fgs groundtruth |
| 95 | + end |
| 96 | + return file |
| 97 | +end |
| 98 | + |
| 99 | + |
| 100 | +""" |
| 101 | + convertfrompackedfunctionnode(fgl, fsym) |
| 102 | +
|
| 103 | +If you get unknown type conversion error when loading a .jld, while using your own |
| 104 | +FunctorInferenceTypes, you should: |
| 105 | +Copy these functions below, and overload in your package with local extented |
| 106 | +FunctorInferenceType definitions. |
| 107 | +See RoME/src/fgos.jl for example. |
| 108 | +""" |
| 109 | +function convertfrompackedfunctionnode(fgl::FactorGraph, |
| 110 | + fsym::Symbol, |
| 111 | + api::DataLayerAPI=localapi ) |
| 112 | + # |
| 113 | + fid = fgl.fIDs[fsym] |
| 114 | + fnc = getData(fgl, fid).fnc #getfnctype(fgl, fid) |
| 115 | + usrtyp = convert(FunctorInferenceType, fnc) |
| 116 | + data = getData(fgl, fid, api=api) |
| 117 | + newtype = FunctionNodeData{GenericWrapParam{usrtyp}} |
| 118 | + cfnd = convert(newtype, data) |
| 119 | + return cfnd, usrtyp |
| 120 | +end |
| 121 | + |
| 122 | +""" |
| 123 | + decodefg(fgs::FactorGraph) |
| 124 | +
|
| 125 | +Unpack PackedFunctionNodeData formats back to regular FunctonNodeData. |
| 126 | +""" |
| 127 | +function decodefg(fgs::FactorGraph; api::DataLayerAPI=localapi) |
| 128 | + fgu = deepcopy(fgs) |
| 129 | + fgu.cg = nothing |
| 130 | + fgu.registeredModuleFunctions = nothing |
| 131 | + fgu.g = Graphs.incdict(Graphs.ExVertex,is_directed=false) |
| 132 | + @showprogress 1 "Decoding variables..." for (vsym,vid) in fgs.IDs |
| 133 | + cpvert = deepcopy(getVert(fgs, vid, api=api)) |
| 134 | + api.addvertex!(fgu, cpvert) #, labels=vnlbls) # currently losing labels |
| 135 | + end |
| 136 | + |
| 137 | + @showprogress 1 "Decoding factors..." for (fsym,fid) in fgu.fIDs |
| 138 | + data,ftyp = convertfrompackedfunctionnode(fgs, fsym) |
| 139 | + # data = FunctionNodeData{ftyp}(Int[], false, false, Int[], m, gwpf) |
| 140 | + newvert = ExVertex(fid,string(fsym)) |
| 141 | + for (key,val) in getVert(fgs,fid,api=api).attributes |
| 142 | + newvert.attributes[key] = val |
| 143 | + end |
| 144 | + setData!(newvert, data) |
| 145 | + api.addvertex!(fgu, newvert) |
| 146 | + end |
| 147 | + fgu.g.inclist = typeof(fgs.g.inclist)() |
| 148 | + |
| 149 | + # iterated over all edges |
| 150 | + @showprogress 1 "Decoding edges..." for (eid, edges) in fgs.g.inclist |
| 151 | + fgu.g.inclist[eid] = Vector{typeof(edges[1])}() |
| 152 | + for ed in edges |
| 153 | + newed = Graphs.Edge(ed.index, |
| 154 | + fgu.g.vertices[ed.source.index], |
| 155 | + fgu.g.vertices[ed.target.index] ) |
| 156 | + push!(fgu.g.inclist[eid], newed) |
| 157 | + end |
| 158 | + end |
| 159 | + |
| 160 | + return fgu |
| 161 | +end |
| 162 | + |
| 163 | +""" |
| 164 | + loadjld(file="tempfg.jld") |
| 165 | +
|
| 166 | +Opposite of savejld(fg, gt=gt, file="tempfg.jl") to load data from file. This function |
| 167 | +uses the unpacking converters for converting all PackedInferenceType to FunctorInferenceType. |
| 168 | +""" |
| 169 | +function loadjld(;file::AbstractString="tempfg.jld") |
| 170 | + dd = JLD.load(file) |
| 171 | + # fgs = jldopen(file,"r") do file |
| 172 | + # read(file, "fgs") |
| 173 | + # end |
| 174 | + fgs, gt = nothing, nothing |
| 175 | + if haskey(dd, "fgs") |
| 176 | + fgs = dd["fgs"] |
| 177 | + else |
| 178 | + error("No factor graph (fgs) data found in this file, only found $(keys(dd))") |
| 179 | + end |
| 180 | + if haskey(dd, "groundtruth") |
| 181 | + gt = dd["groundtruth"] |
| 182 | + println("Also found ground truth data") |
| 183 | + end |
| 184 | + fgd = decodefg(fgs) |
| 185 | + return fgd, gt |
| 186 | +end |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | +function ls(fgl::FactorGraph, lbl::Symbol; api::DataLayerAPI=dlapi, ring::Int=1) |
| 192 | + # TODO ring functionality must still be implemented |
| 193 | + lsa = Symbol[] |
| 194 | + # v = nothing |
| 195 | + if haskey(fgl.IDs, lbl) |
| 196 | + id = fgl.IDs[lbl] |
| 197 | + else |
| 198 | + return lsa |
| 199 | + end |
| 200 | + # this is unnecessary |
| 201 | + v = getVert(fgl,id, api=api) |
| 202 | + for outn in api.outneighbors(fgl, v) |
| 203 | + # if outn.attributes["ready"] = 1 && outn.attributes["backendset"]=1 |
| 204 | + push!(lsa, Symbol(outn.label)) |
| 205 | + # end |
| 206 | + end |
| 207 | + return lsa |
| 208 | +end |
| 209 | +ls(fgl::FactorGraph, lbl::T) where {T <: AbstractString} = ls(fgl, Symbol(lbl)) |
| 210 | + |
| 211 | +function ls(fgl::FactorGraph) |
| 212 | + k = collect(keys(fgl.IDs)) |
| 213 | + l = Int[] |
| 214 | + x = Int[] |
| 215 | + for kk in k |
| 216 | + kstr = string(kk) |
| 217 | + val = parse(Int,kstr[2:end]) # kk |
| 218 | + if kstr[1] == 'l' |
| 219 | + push!(l,val) |
| 220 | + elseif kstr[1] == 'x' |
| 221 | + push!(x,val) |
| 222 | + end |
| 223 | + end |
| 224 | + l = sort(l) |
| 225 | + x = sort(x) |
| 226 | + ll = Array{Symbol,1}(length(l)) |
| 227 | + xx = Array{Symbol,1}(length(x)) |
| 228 | + for i in 1:length(l) |
| 229 | + ll[i] = Symbol(string("l",l[i])) |
| 230 | + end |
| 231 | + for i in 1:length(x) |
| 232 | + xx[i] = Symbol(string("x",x[i])) |
| 233 | + end |
| 234 | + return xx,ll |
| 235 | +end |
| 236 | + |
| 237 | +function lsf(fgl::FactorGraph, lbl::Symbol; api::DataLayerAPI=dlapi) |
| 238 | + lsa = Symbol[] |
| 239 | + # v = Union{} |
| 240 | + if haskey(fgl.fIDs, lbl) |
| 241 | + id = fgl.fIDs[lbl] |
| 242 | + else |
| 243 | + return lsa |
| 244 | + end |
| 245 | + v = getVert(fgl, id, api=api) # fgl.g.vertices[id] #fgl.f[id] |
| 246 | + for outn in api.outneighbors(fgl, v) # out_neighbors(v, fgl.g) |
| 247 | + push!(lsa, Symbol(outn.label)) |
| 248 | + end |
| 249 | + return lsa |
| 250 | +end |
| 251 | +lsf{T <: AbstractString}(fgl::FactorGraph, lbl::T) = lsf(fgl,Symbol(lbl)) |
| 252 | + |
| 253 | +function lsf{T <: FunctorInferenceType}(fgl::FactorGraph, |
| 254 | + mt::Type{T}; |
| 255 | + api::DataLayerAPI=dlapi ) |
| 256 | + # |
| 257 | + syms = Symbol[] |
| 258 | + for (fsym,fid) in fgl.fIDs |
| 259 | + if typeof(getfnctype(fgl, fid, api=api))==T |
| 260 | + push!(syms, fsym) |
| 261 | + end |
| 262 | + end |
| 263 | + return syms |
| 264 | +end |
| 265 | + |
| 266 | +function ls2(fgl::FactorGraph, vsym::Symbol) |
| 267 | + xxf = ls(fgl, vsym) |
| 268 | + xlxl = Symbol[] |
| 269 | + for xf in xxf |
| 270 | + xx = lsf(fgl,xf) |
| 271 | + xlxl = union(xlxl, xx) |
| 272 | + end |
| 273 | + xlxl = setdiff(xlxl, [vsym]) |
| 274 | + return xlxl |
| 275 | +end |
| 276 | + |
| 277 | + |
| 278 | +""" |
| 279 | + landmarks(fgl::FactorGraph, vsym::Symbol) |
| 280 | +
|
| 281 | +Return Vector{Symbol} of landmarks attached to vertex vsym in fgl. |
| 282 | +""" |
| 283 | +function landmarks(fgl::FactorGraph, vsym::Symbol) |
| 284 | + fsyms = ls(fgl, vsym) |
| 285 | + lms = Symbol[] |
| 286 | + for fs in fsyms |
| 287 | + for varv = lsf(fgl, fs) |
| 288 | + if string(varv)[1] == 'l' |
| 289 | + push!(lms, varv) |
| 290 | + end |
| 291 | + end |
| 292 | + end |
| 293 | + lms |
| 294 | +end |
| 295 | + |
| 296 | + |
| 297 | + |
| 298 | + |
| 299 | + |
| 300 | + |
| 301 | +# |
0 commit comments