LIBRARY
Logical.Tests.LogicGates
Validation test for logic gate blocks: And, Or, Xor, Nand, Nor.
Uses a Ramp source with height=4, duration=4: ramp(t) = offset + t. Two GreaterThreshold blocks convert ramp to Boolean by comparing against thresholds at -100 (always true) or 100 (always false).
Four test cases cover the full truth table by overriding thresholds:
TT (both true): bool1.threshold=-100, bool2.threshold=-100
TF (true,false): bool1.threshold=-100, bool2.threshold=100
FT (false,true): bool1.threshold=100, bool2.threshold=-100
FF (both false): bool1.threshold=100, bool2.threshold=100
Usage
BlockComponents.Logical.Tests.LogicGates()
Behavior
julia
using BlockComponents #hide
using ModelingToolkit #hide
@named sys = BlockComponents.Logical.Tests.LogicGates() #hide
let eqs = full_equations(sys); Base.length(eqs) > 25 ? nothing : eqs end #hide<< @example-block not executed in draft mode >>Source
dyad
"""
Validation test for logic gate blocks: And, Or, Xor, Nand, Nor.
Uses a Ramp source with height=4, duration=4: ramp(t) = offset + t.
Two GreaterThreshold blocks convert ramp to Boolean by comparing against
thresholds at -100 (always true) or 100 (always false).
Four test cases cover the full truth table by overriding thresholds:
- TT (both true): bool1.threshold=-100, bool2.threshold=-100
- TF (true,false): bool1.threshold=-100, bool2.threshold=100
- FT (false,true): bool1.threshold=100, bool2.threshold=-100
- FF (both false): bool1.threshold=100, bool2.threshold=100
"""
test component LogicGates
"Ramp: ramp(t) = offset + t for t in [0, 4]"
ramp = BlockComponents.Sources.Ramp(height = 4, duration = 4, offset = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 230, "x2": 120, "y2": 330, "rot": 0}
},
"tags": []
}
}
"Boolean input 1: threshold=-100 means always true by default"
bool1 = BlockComponents.Logical.GreaterThreshold(threshold = -100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 161, "y1": 230, "x2": 261, "y2": 330, "rot": 0}
},
"tags": []
}
}
"Boolean input 2: threshold=-100 means always true by default"
bool2 = BlockComponents.Logical.GreaterThreshold(threshold = -100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 161, "y1": 406, "x2": 261, "y2": 506, "rot": 0}
},
"tags": []
}
}
"Logic gates under test"
and1 = BlockComponents.Logical.And() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 380, "x2": 411, "y2": 480, "rot": 0}
},
"tags": []
}
}
or1 = BlockComponents.Logical.Or() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 500, "x2": 411, "y2": 600, "rot": 0}
},
"tags": []
}
}
xor1 = BlockComponents.Logical.Xor() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 320, "y1": 20, "x2": 420, "y2": 120, "rot": 0}
},
"tags": []
}
}
nand1 = BlockComponents.Logical.Nand() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 140, "x2": 411, "y2": 240, "rot": 0}
},
"tags": []
}
}
nor1 = BlockComponents.Logical.Nor() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 260, "x2": 411, "y2": 360, "rot": 0}
},
"tags": []
}
}
relations
# Boolean signal generation from ramp
connect(ramp.y, bool1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(ramp.y, bool2.u) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 140, "y": 456}], "E": 2}],
"junctions": [{"x": 140, "y": 280}],
"renderStyle": "standard"
}
}
# All gates: bool1 → u1, bool2 → u2
connect(bool1.y, and1.u1) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": -2},
{"S": -2, "M": [], "E": 2}
],
"junctions": [{"x": 291, "y": 280}, {"x": 291, "y": 400}],
"renderStyle": "standard"
}
}
connect(bool2.y, and1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bool1.y, or1.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 280}, {"x": 291, "y": 520}], "E": 2}],
"renderStyle": "standard"
}
}
connect(bool2.y, or1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 281, "y": 576}], "E": 2}],
"junctions": [{"x": 281, "y": 456}],
"renderStyle": "standard"
}
}
connect(bool1.y, xor1.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 280}, {"x": 291, "y": 40}], "E": 2}],
"renderStyle": "standard"
}
}
connect(bool2.y, xor1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 281, "y": 456}, {"x": 281, "y": 96}], "E": 2}],
"renderStyle": "standard"
}
}
connect(bool1.y, nand1.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 280}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 291, "y": 160}],
"renderStyle": "standard"
}
}
connect(bool2.y, nand1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 281, "y": 456}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 281, "y": 216}],
"renderStyle": "standard"
}
}
connect(bool1.y, nor1.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bool2.y, nor1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 281, "y": 456}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 281, "y": 336}],
"renderStyle": "standard"
}
}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"TT": {
"stop": 1,
"params": {"bool1.threshold": -100, "bool2.threshold": -100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
},
"TF": {
"stop": 1,
"params": {"bool1.threshold": -100, "bool2.threshold": 100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
},
"FT": {
"stop": 1,
"params": {"bool1.threshold": 100, "bool2.threshold": -100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
},
"FF": {
"stop": 1,
"params": {"bool1.threshold": 100, "bool2.threshold": 100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
}
}
}
}
endFlattened Source
dyad
"""
Validation test for logic gate blocks: And, Or, Xor, Nand, Nor.
Uses a Ramp source with height=4, duration=4: ramp(t) = offset + t.
Two GreaterThreshold blocks convert ramp to Boolean by comparing against
thresholds at -100 (always true) or 100 (always false).
Four test cases cover the full truth table by overriding thresholds:
- TT (both true): bool1.threshold=-100, bool2.threshold=-100
- TF (true,false): bool1.threshold=-100, bool2.threshold=100
- FT (false,true): bool1.threshold=100, bool2.threshold=-100
- FF (both false): bool1.threshold=100, bool2.threshold=100
"""
test component LogicGates
"Ramp: ramp(t) = offset + t for t in [0, 4]"
ramp = BlockComponents.Sources.Ramp(height = 4, duration = 4, offset = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 230, "x2": 120, "y2": 330, "rot": 0}
},
"tags": []
}
}
"Boolean input 1: threshold=-100 means always true by default"
bool1 = BlockComponents.Logical.GreaterThreshold(threshold = -100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 161, "y1": 230, "x2": 261, "y2": 330, "rot": 0}
},
"tags": []
}
}
"Boolean input 2: threshold=-100 means always true by default"
bool2 = BlockComponents.Logical.GreaterThreshold(threshold = -100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 161, "y1": 406, "x2": 261, "y2": 506, "rot": 0}
},
"tags": []
}
}
"Logic gates under test"
and1 = BlockComponents.Logical.And() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 380, "x2": 411, "y2": 480, "rot": 0}
},
"tags": []
}
}
or1 = BlockComponents.Logical.Or() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 500, "x2": 411, "y2": 600, "rot": 0}
},
"tags": []
}
}
xor1 = BlockComponents.Logical.Xor() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 320, "y1": 20, "x2": 420, "y2": 120, "rot": 0}
},
"tags": []
}
}
nand1 = BlockComponents.Logical.Nand() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 140, "x2": 411, "y2": 240, "rot": 0}
},
"tags": []
}
}
nor1 = BlockComponents.Logical.Nor() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 311, "y1": 260, "x2": 411, "y2": 360, "rot": 0}
},
"tags": []
}
}
relations
# Boolean signal generation from ramp
connect(ramp.y, bool1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(ramp.y, bool2.u) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 140, "y": 456}], "E": 2}],
"junctions": [{"x": 140, "y": 280}],
"renderStyle": "standard"
}
}
# All gates: bool1 → u1, bool2 → u2
connect(bool1.y, and1.u1) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": -2},
{"S": -2, "M": [], "E": 2}
],
"junctions": [{"x": 291, "y": 280}, {"x": 291, "y": 400}],
"renderStyle": "standard"
}
}
connect(bool2.y, and1.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bool1.y, or1.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 280}, {"x": 291, "y": 520}], "E": 2}],
"renderStyle": "standard"
}
}
connect(bool2.y, or1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 281, "y": 576}], "E": 2}],
"junctions": [{"x": 281, "y": 456}],
"renderStyle": "standard"
}
}
connect(bool1.y, xor1.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 280}, {"x": 291, "y": 40}], "E": 2}],
"renderStyle": "standard"
}
}
connect(bool2.y, xor1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 281, "y": 456}, {"x": 281, "y": 96}], "E": 2}],
"renderStyle": "standard"
}
}
connect(bool1.y, nand1.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 280}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 291, "y": 160}],
"renderStyle": "standard"
}
}
connect(bool2.y, nand1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 281, "y": 456}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 281, "y": 216}],
"renderStyle": "standard"
}
}
connect(bool1.y, nor1.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bool2.y, nor1.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 281, "y": 456}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 281, "y": 336}],
"renderStyle": "standard"
}
}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"TT": {
"stop": 1,
"params": {"bool1.threshold": -100, "bool2.threshold": -100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
},
"TF": {
"stop": 1,
"params": {"bool1.threshold": -100, "bool2.threshold": 100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
},
"FT": {
"stop": 1,
"params": {"bool1.threshold": 100, "bool2.threshold": -100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
},
"FF": {
"stop": 1,
"params": {"bool1.threshold": 100, "bool2.threshold": 100},
"expect": {
"signals": ["bool1.y", "bool2.y", "and1.y", "or1.y", "xor1.y", "nand1.y", "nor1.y"]
}
}
}
}
}
endTest Cases
julia
using BlockComponents
using DyadInterface: TransientAnalysis, rebuild_sol, ODEAlg
using ModelingToolkit: toggle_namespacing, get_initial_conditions, @named
using CSV, DataFrames, Plots
snapshotsdir = joinpath(dirname(dirname(pathof(BlockComponents))), "test", "snapshots")<< @setup-block not executed in draft mode >>Test Case TT
julia
@named model_TT = BlockComponents.Logical.Tests.LogicGates(bool1.threshold=-100, bool2.threshold=-100)
model_TT = toggle_namespacing(model_TT, false)
model_TT = toggle_namespacing(model_TT, true)
result_TT = TransientAnalysis(; model = model_TT, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_TT = rebuild_sol(result_TT)<< @setup-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.bool1.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.bool1.y], width=2, label="Actual value of bool1.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of bool1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.bool2.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.bool2.y], width=2, label="Actual value of bool2.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of bool2.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.and1.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.and1.y], width=2, label="Actual value of and1.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of and1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.or1.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.or1.y], width=2, label="Actual value of or1.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of or1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.xor1.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.xor1.y], width=2, label="Actual value of xor1.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of xor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.nand1.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.nand1.y], width=2, label="Actual value of nand1.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of nand1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TT = DataFrame(:t => sol_TT[:t], :actual => sol_TT[model_TT.nor1.y])
dfr_TT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TT_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TT, idxs=[model_TT.nor1.y], width=2, label="Actual value of nor1.y")
if !isnothing(dfr_TT)
scatter!(plt, dfr_TT.t, dfr_TT.expected, mc=:red, ms=3, label="Expected value of nor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>Test Case TF
julia
@named model_TF = BlockComponents.Logical.Tests.LogicGates(bool1.threshold=-100, bool2.threshold=100)
model_TF = toggle_namespacing(model_TF, false)
model_TF = toggle_namespacing(model_TF, true)
result_TF = TransientAnalysis(; model = model_TF, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_TF = rebuild_sol(result_TF)<< @setup-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.bool1.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.bool1.y], width=2, label="Actual value of bool1.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of bool1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.bool2.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.bool2.y], width=2, label="Actual value of bool2.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of bool2.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.and1.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.and1.y], width=2, label="Actual value of and1.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of and1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.or1.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.or1.y], width=2, label="Actual value of or1.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of or1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.xor1.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.xor1.y], width=2, label="Actual value of xor1.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of xor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.nand1.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.nand1.y], width=2, label="Actual value of nand1.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of nand1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_TF = DataFrame(:t => sol_TF[:t], :actual => sol_TF[model_TF.nor1.y])
dfr_TF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_TF_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_TF, idxs=[model_TF.nor1.y], width=2, label="Actual value of nor1.y")
if !isnothing(dfr_TF)
scatter!(plt, dfr_TF.t, dfr_TF.expected, mc=:red, ms=3, label="Expected value of nor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>Test Case FT
julia
@named model_FT = BlockComponents.Logical.Tests.LogicGates(bool1.threshold=100, bool2.threshold=-100)
model_FT = toggle_namespacing(model_FT, false)
model_FT = toggle_namespacing(model_FT, true)
result_FT = TransientAnalysis(; model = model_FT, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_FT = rebuild_sol(result_FT)<< @setup-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.bool1.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.bool1.y], width=2, label="Actual value of bool1.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of bool1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.bool2.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.bool2.y], width=2, label="Actual value of bool2.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of bool2.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.and1.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.and1.y], width=2, label="Actual value of and1.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of and1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.or1.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.or1.y], width=2, label="Actual value of or1.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of or1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.xor1.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.xor1.y], width=2, label="Actual value of xor1.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of xor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.nand1.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.nand1.y], width=2, label="Actual value of nand1.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of nand1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FT = DataFrame(:t => sol_FT[:t], :actual => sol_FT[model_FT.nor1.y])
dfr_FT = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FT_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FT, idxs=[model_FT.nor1.y], width=2, label="Actual value of nor1.y")
if !isnothing(dfr_FT)
scatter!(plt, dfr_FT.t, dfr_FT.expected, mc=:red, ms=3, label="Expected value of nor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>Test Case FF
julia
@named model_FF = BlockComponents.Logical.Tests.LogicGates(bool1.threshold=100, bool2.threshold=100)
model_FF = toggle_namespacing(model_FF, false)
model_FF = toggle_namespacing(model_FF, true)
result_FF = TransientAnalysis(; model = model_FF, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_FF = rebuild_sol(result_FF)<< @setup-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.bool1.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.bool1.y], width=2, label="Actual value of bool1.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of bool1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.bool2.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.bool2.y], width=2, label="Actual value of bool2.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of bool2.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.and1.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.and1.y], width=2, label="Actual value of and1.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of and1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.or1.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.or1.y], width=2, label="Actual value of or1.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of or1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.xor1.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.xor1.y], width=2, label="Actual value of xor1.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of xor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.nand1.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.nand1.y], width=2, label="Actual value of nand1.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of nand1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_FF = DataFrame(:t => sol_FF[:t], :actual => sol_FF[model_FF.nor1.y])
dfr_FF = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicGates_FF_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_FF, idxs=[model_FF.nor1.y], width=2, label="Actual value of nor1.y")
if !isnothing(dfr_FF)
scatter!(plt, dfr_FF.t, dfr_FF.expected, mc=:red, ms=3, label="Expected value of nor1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>