AlgebraicJulia / StockFlow.jl

https://algebraicjulia.github.io/StockFlow.jl/
MIT License
63 stars 6 forks source link

Serializing Stock & Flow objects fails #91

Open djinnome opened 11 months ago

djinnome commented 11 months ago

Hi folks,

I tried serializing the StockFlow acset examples in https://github.com/AlgebraicJulia/StockFlow.jl/blob/master/examples/primitive_schema_examples/Covid19_composition_model_in_paper.ipynb

to json with:

using StockFlow

using Catlab.CategoricalAlgebra
using LabelledArrays
using OrdinaryDiffEq
using Plots

using Catlab.Graphics
using Catlab.Programs
using Catlab.WiringDiagrams

# define functions ϕ of flows in the SEIRH model
fNewIncidence(u,p,t)=p.β*u.S*u.I/p.N
fNewInfectious(u,p,t)=u.E*p.ri
fNewRecovery(u,p,t)=u.I/p.tr * (1.0-p.fH )
fWaningImmunityR(u,p,t)=u.R/p.tw
fHICUAdmission(u,p,t) = u.I/p.tr * p.fH * p.fICU
fHNICUAdmission(u,p,t) = u.I/p.tr * p.fH * (1.0-p.fICU)
fOutICU(u,p,t) = u.HICU/p.tICU
fRecoveryH(u,p,t)= u.HNICU/p.tH

# StockAndFlowp(stocks,
#               (flow=>function, upstream=>downstream) => stocks linked)
seirh = StockAndFlowp((:S, :E, :I, :R, :HICU, :HNICU), 
   ((:NewIncidence=>fNewIncidence, :S=>:E) => (:S, :I), 
    (:NewInfectious=>fNewInfectious, :E=>:I) => :E,
    (:NewRecovery=>fNewRecovery, :I=>:R) => :I, 
    (:WaningImmunityR=>fWaningImmunityR, :R=>:S) => :R,
    (:HICUAdmission=>fHICUAdmission, :I=>:HICU) => :I, 
    (:HNICUAdmission=>fHNICUAdmission, :I=>:HNICU) => :I, 
    (:OutICU=>fOutICU, :HICU=>:HNICU) => :HICU,
    (:RecoveryH=>fRecoveryH, :HNICU=>:R) => :HNICU))

write_json_acset(seirh, "seirh.json")

But I got this error instead:

Cannot serialize type typeof(fNewIncidence)

Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] lower
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:47 [inlined]
  [3] show_json(io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, a::Function)
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:348
  [4] show_pair(io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, k::Symbol, v::Function)
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:257
  [5] show_pair(io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, kv::Pair{Symbol, Any})
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:259
  [6] (::JSON.Writer.var"#1#2"{JSON.Writer.CompactContext{IOBuffer}, JSON.Serializations.StandardSerialization, NamedTuple{(:_id, :u, :d, :fname, :ϕf), Tuple{Int64, Int64, Int64, Symbol, typeof(fNewIncidence)}}})()
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:300
  [7] recursive_cycle_check(f::JSON.Writer.var"#1#2"{JSON.Writer.CompactContext{IOBuffer}, JSON.Serializations.StandardSerialization, NamedTuple{(:_id, :u, :d, :fname, :ϕf), Tuple{Int64, Int64, Int64, Symbol, typeof(fNewIncidence)}}}, io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, id::UInt64)
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:291
  [8] show_json
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:297 [inlined]
  [9] show_element(io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, x::NamedTuple{(:_id, :u, :d, :fname, :ϕf), Tuple{Int64, Int64, Int64, Symbol, typeof(fNewIncidence)}})
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:234
 [10] (::JSON.Writer.var"#5#6"{JSON.Writer.CompactContext{IOBuffer}, JSON.Serializations.StandardSerialization, Vector{NamedTuple{(:_id, :u, :d, :fname, :ϕf)}}})()
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:326
 [11] recursive_cycle_check(f::JSON.Writer.var"#5#6"{JSON.Writer.CompactContext{IOBuffer}, JSON.Serializations.StandardSerialization, Vector{NamedTuple{(:_id, :u, :d, :fname, :ϕf)}}}, io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, id::UInt64)
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:291
 [12] show_json
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:323 [inlined]
 [13] show_pair
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:257 [inlined]
 [14] show_pair(io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, kv::Pair{Symbol, Vector{NamedTuple{(:_id, :u, :d, :fname, :ϕf)}}})
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:259
 [15] (::JSON.Writer.var"#1#2"{JSON.Writer.CompactContext{IOBuffer}, JSON.Serializations.StandardSerialization, OrderedCollections.OrderedDict{Symbol, Any}})()
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:300
 [16] recursive_cycle_check(f::JSON.Writer.var"#1#2"{JSON.Writer.CompactContext{IOBuffer}, JSON.Serializations.StandardSerialization, OrderedCollections.OrderedDict{Symbol, Any}}, io::JSON.Writer.CompactContext{IOBuffer}, s::JSON.Serializations.StandardSerialization, id::UInt64)
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:291
 [17] show_json
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:297 [inlined]
 [18] #show_json#9
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:359 [inlined]
 [19] show_json
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:357 [inlined]
 [20] print(io::IOBuffer, obj::OrderedCollections.OrderedDict{Symbol, Any})
    @ JSON.Writer ~/.julia/packages/JSON/93Ea8/src/Writer.jl:383
 [21] sprint(f::Function, args::OrderedCollections.OrderedDict{Symbol, Any}; context::Nothing, sizehint::Int64)
    @ Base ./strings/io.jl:114
 [22] sprint
    @ ./strings/io.jl:107 [inlined]
 [23] json
    @ ~/.julia/packages/JSON/93Ea8/src/Writer.jl:399 [inlined]
 [24] #7
    @ ~/.julia/packages/ACSets/nILxS/src/JSONACSets.jl:91 [inlined]
 [25] open(::ACSets.JSONACSets.var"#7#8"{StockAndFlowp}, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base ./io.jl:395
 [26] open
    @ ./io.jl:392 [inlined]
 [27] write_json_acset(x::StockAndFlowp, fname::String)
    @ ACSets.JSONACSets ~/.julia/packages/ACSets/nILxS/src/JSONACSets.jl:90
 [28] top-level scope
    @ In[5]:1

I got the same error with Vaccine model B, Persistent Asymptomaticity Model C, and the COVID19 model.

neonWhiteout commented 11 months ago

It may work with the new models; I'll have a look.

djinnome commented 11 months ago

OK, on advice from @jpfairbanks , I tried: https://github.com/AlgebraicJulia/StockFlow.jl/blob/master/docs/src/json.md

Interestingly, when I ran:

JSON3.pretty(generate_json_acset(sir))

I got:

{
    "Flow": [
        {
            "u": 1,
            "d": 2,
            "fname": "NewIncidence",
            "ϕf": "p.cβ*u.S*u.I/p.N"
        },
        {
            "u": 2,
            "d": 3,
            "fname": "NewRecovery",
            "ϕf": "u.I/p.tr"
        }
    ],
    "Stock": [
        {
            "sname": "S"
        },
        {
            "sname": "I"
        },
        {
            "sname": "R"
        }
    ],
    "Link": [
        {
            "s": 1,
            "t": 1
        },
        {
            "s": 2,
            "t": 1
        },
        {
            "s": 2,
            "t": 2
        }
    ]
}

but when I tried:

open("sir.json", "w") do io
     JSON3.pretty(io, generate_json_acset(sir))
end

I got an empty sir.json file.

jpfairbanks commented 11 months ago

The only explanation I could see for the empty file is not flushing the file handle. Did you end the julia process before looking at the file?