LIBRARY
Logical.Tests.LogicalValidation
Validation test for all Logical blocks with deterministic expected outputs.
Uses a Ramp with height=4, duration=4: ramp(t) = offset + t. At t=1 (the common stop time), ramp = offset + 1. A Constant at 1.0 serves as the second input for two-input comparisons. All threshold blocks use threshold = 1.0.
Three test cases via params overriding ramp.offset:
below (offset=-2): ramp(1)=-1.0 < threshold
equal (offset=0): ramp(1)=1.0 = threshold
above (offset=1.5): ramp(1)=2.5 > threshold
Usage
BlockComponents.Logical.Tests.LogicalValidation()
Behavior
julia
using BlockComponents #hide
using ModelingToolkit #hide
@named sys = BlockComponents.Logical.Tests.LogicalValidation() #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 all Logical blocks with deterministic expected outputs.
Uses a Ramp with height=4, duration=4: ramp(t) = offset + t.
At t=1 (the common stop time), ramp = offset + 1.
A Constant at 1.0 serves as the second input for two-input comparisons.
All threshold blocks use threshold = 1.0.
Three test cases via `params` overriding `ramp.offset`:
- below (offset=-2): ramp(1)=-1.0 < threshold
- equal (offset=0): ramp(1)=1.0 = threshold
- above (offset=1.5): ramp(1)=2.5 > threshold
"""
test component LogicalValidation
"Ramp: ramp(t) = offset + t for t in [0, 4]"
ramp = BlockComponents.Sources.Ramp(height = 4, duration = 4, offset = -2) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 1200, "x2": 120, "y2": 1300, "rot": 0}
},
"tags": []
}
}
"Constant reference at 1.0"
const1 = BlockComponents.Sources.Constant(k = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 405, "x2": 120, "y2": 505, "rot": 0}
},
"tags": []
}
}
"Constant reference at 10.0 for Switch test"
const10 = BlockComponents.Sources.Constant(k = 10.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 1301, "x2": 271, "y2": 1401, "rot": 0}
},
"tags": []
}
}
"Always-true boolean source (threshold well below ramp range)"
boolTrue = BlockComponents.Logical.GreaterThreshold(threshold = -100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 620, "x2": 271, "y2": 720, "rot": 0}
},
"tags": []
}
}
"Always-false boolean source (threshold well above ramp range)"
boolFalse = BlockComponents.Logical.GreaterThreshold(threshold = 100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 740, "x2": 271, "y2": 840, "rot": 0}
},
"tags": []
}
}
"Threshold comparisons (threshold = 1.0)"
gt_thresh = BlockComponents.Logical.GreaterThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 980, "x2": 271, "y2": 1080, "rot": 0}
},
"tags": []
}
}
ge_thresh = BlockComponents.Logical.GreaterEqualThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 1100, "x2": 271, "y2": 1200, "rot": 0}
},
"tags": []
}
}
lt_thresh = BlockComponents.Logical.LessThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 860, "x2": 271, "y2": 960, "rot": 0}
},
"tags": []
}
}
le_thresh = BlockComponents.Logical.LessEqualThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 500, "x2": 271, "y2": 600, "rot": 0}
},
"tags": []
}
}
"Two-input comparisons: ramp (u1) vs const1 (u2)"
gt = BlockComponents.Logical.Greater() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 140, "x2": 271, "y2": 240, "rot": 0}
},
"tags": []
}
}
ge = BlockComponents.Logical.GreaterEqual() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 380, "x2": 271, "y2": 480, "rot": 0}
},
"tags": []
}
}
lt = BlockComponents.Logical.Less() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 260, "x2": 271, "y2": 360, "rot": 0}
},
"tags": []
}
}
le = BlockComponents.Logical.LessEqual() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 180, "y1": 20, "x2": 280, "y2": 120, "rot": 0}
},
"tags": []
}
}
"Not: inverts GreaterThreshold output"
not1 = BlockComponents.Logical.Not() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 312, "y1": 980, "x2": 412, "y2": 1080, "rot": 0}
},
"tags": []
}
}
"Switch: selects ramp (u1) when gt_thresh true, else const10 (u3)"
sw = BlockComponents.Logical.Switch() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 312, "y1": 1232, "x2": 412, "y2": 1332, "rot": 0}
},
"tags": []
}
}
"LogicalSwitch: selects boolTrue (u1) when gt_thresh true, else boolFalse (u3)"
lsw = BlockComponents.Logical.LogicalSwitch() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 312, "y1": 703, "x2": 412, "y2": 803, "rot": 0}
},
"tags": []
}
}
relations
# Threshold comparisons: all driven by ramp
connect(ramp.y, gt_thresh.u) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": -2},
{"S": -2, "M": [], "E": 2}
],
"junctions": [{"x": 140, "y": 1250}, {"x": 140, "y": 1030}],
"renderStyle": "standard"
}
}
connect(ramp.y, ge_thresh.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 1150}],
"renderStyle": "standard"
}
}
connect(ramp.y, lt_thresh.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 910}],
"renderStyle": "standard"
}
}
connect(ramp.y, le_thresh.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 550}],
"renderStyle": "standard"
}
}
# Two-input comparisons: ramp (u1) vs const1 (u2)
connect(ramp.y, gt.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 159}],
"renderStyle": "standard"
}
}
connect(const1.y, gt.u2) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": -2},
{"S": -2, "M": [], "E": 2}
],
"junctions": [{"x": 150, "y": 455}, {"x": 150, "y": 215}],
"renderStyle": "standard"
}
}
connect(ramp.y, ge.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 399}],
"renderStyle": "standard"
}
}
connect(const1.y, ge.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(ramp.y, lt.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 279}],
"renderStyle": "standard"
}
}
connect(const1.y, lt.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 150, "y": 455}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 150, "y": 335}],
"renderStyle": "standard"
}
}
connect(ramp.y, le.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}, {"x": 140, "y": 39}], "E": 2}],
"renderStyle": "standard"
}
}
connect(const1.y, le.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 150, "y": 455}, {"x": 150, "y": 95}], "E": 2}],
"renderStyle": "standard"
}
}
# Not: inverts GreaterThreshold
connect(gt_thresh.y, not1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
# Boolean sources for LogicalSwitch
connect(ramp.y, boolTrue.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 670}],
"renderStyle": "standard"
}
}
connect(ramp.y, boolFalse.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 790}],
"renderStyle": "standard"
}
}
# Switch: u2=gt_thresh controls between ramp (u1) and const10 (u3)
connect(ramp.y, sw.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(gt_thresh.y, sw.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 291, "y": 1282}], "E": 2}],
"junctions": [{"x": 291, "y": 1030}],
"renderStyle": "standard"
}
}
connect(const10.y, sw.u3) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 1351}, {"x": 291, "y": 1314}], "E": 2}],
"renderStyle": "standard"
}
}
# LogicalSwitch: u2=gt_thresh controls between boolTrue (u1) and boolFalse (u3)
connect(boolTrue.y, lsw.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 670}, {"x": 291, "y": 716}], "E": 2}],
"renderStyle": "standard"
}
}
connect(gt_thresh.y, lsw.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 1030}, {"x": 291, "y": 753}], "E": 2}],
"renderStyle": "standard"
}
}
connect(boolFalse.y, lsw.u3) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"below": {
"stop": 1,
"params": {"ramp.offset": -2},
"expect": {
"signals": [
"ramp.y",
"gt_thresh.y",
"ge_thresh.y",
"lt_thresh.y",
"le_thresh.y",
"gt.y",
"ge.y",
"lt.y",
"le.y",
"not1.y",
"sw.y",
"lsw.y"
]
}
},
"equal": {
"stop": 1,
"params": {"ramp.offset": 0},
"expect": {
"signals": [
"ramp.y",
"gt_thresh.y",
"ge_thresh.y",
"lt_thresh.y",
"le_thresh.y",
"gt.y",
"ge.y",
"lt.y",
"le.y",
"not1.y",
"sw.y",
"lsw.y"
]
}
},
"above": {
"stop": 1,
"params": {"ramp.offset": 1.5},
"expect": {
"signals": [
"ramp.y",
"gt_thresh.y",
"ge_thresh.y",
"lt_thresh.y",
"le_thresh.y",
"gt.y",
"ge.y",
"lt.y",
"le.y",
"not1.y",
"sw.y",
"lsw.y"
]
}
}
}
}
}
endFlattened Source
dyad
"""
Validation test for all Logical blocks with deterministic expected outputs.
Uses a Ramp with height=4, duration=4: ramp(t) = offset + t.
At t=1 (the common stop time), ramp = offset + 1.
A Constant at 1.0 serves as the second input for two-input comparisons.
All threshold blocks use threshold = 1.0.
Three test cases via `params` overriding `ramp.offset`:
- below (offset=-2): ramp(1)=-1.0 < threshold
- equal (offset=0): ramp(1)=1.0 = threshold
- above (offset=1.5): ramp(1)=2.5 > threshold
"""
test component LogicalValidation
"Ramp: ramp(t) = offset + t for t in [0, 4]"
ramp = BlockComponents.Sources.Ramp(height = 4, duration = 4, offset = -2) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 1200, "x2": 120, "y2": 1300, "rot": 0}
},
"tags": []
}
}
"Constant reference at 1.0"
const1 = BlockComponents.Sources.Constant(k = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 405, "x2": 120, "y2": 505, "rot": 0}
},
"tags": []
}
}
"Constant reference at 10.0 for Switch test"
const10 = BlockComponents.Sources.Constant(k = 10.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 1301, "x2": 271, "y2": 1401, "rot": 0}
},
"tags": []
}
}
"Always-true boolean source (threshold well below ramp range)"
boolTrue = BlockComponents.Logical.GreaterThreshold(threshold = -100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 620, "x2": 271, "y2": 720, "rot": 0}
},
"tags": []
}
}
"Always-false boolean source (threshold well above ramp range)"
boolFalse = BlockComponents.Logical.GreaterThreshold(threshold = 100.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 740, "x2": 271, "y2": 840, "rot": 0}
},
"tags": []
}
}
"Threshold comparisons (threshold = 1.0)"
gt_thresh = BlockComponents.Logical.GreaterThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 980, "x2": 271, "y2": 1080, "rot": 0}
},
"tags": []
}
}
ge_thresh = BlockComponents.Logical.GreaterEqualThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 1100, "x2": 271, "y2": 1200, "rot": 0}
},
"tags": []
}
}
lt_thresh = BlockComponents.Logical.LessThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 860, "x2": 271, "y2": 960, "rot": 0}
},
"tags": []
}
}
le_thresh = BlockComponents.Logical.LessEqualThreshold(threshold = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 500, "x2": 271, "y2": 600, "rot": 0}
},
"tags": []
}
}
"Two-input comparisons: ramp (u1) vs const1 (u2)"
gt = BlockComponents.Logical.Greater() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 140, "x2": 271, "y2": 240, "rot": 0}
},
"tags": []
}
}
ge = BlockComponents.Logical.GreaterEqual() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 380, "x2": 271, "y2": 480, "rot": 0}
},
"tags": []
}
}
lt = BlockComponents.Logical.Less() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 171, "y1": 260, "x2": 271, "y2": 360, "rot": 0}
},
"tags": []
}
}
le = BlockComponents.Logical.LessEqual() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 180, "y1": 20, "x2": 280, "y2": 120, "rot": 0}
},
"tags": []
}
}
"Not: inverts GreaterThreshold output"
not1 = BlockComponents.Logical.Not() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 312, "y1": 980, "x2": 412, "y2": 1080, "rot": 0}
},
"tags": []
}
}
"Switch: selects ramp (u1) when gt_thresh true, else const10 (u3)"
sw = BlockComponents.Logical.Switch() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 312, "y1": 1232, "x2": 412, "y2": 1332, "rot": 0}
},
"tags": []
}
}
"LogicalSwitch: selects boolTrue (u1) when gt_thresh true, else boolFalse (u3)"
lsw = BlockComponents.Logical.LogicalSwitch() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 312, "y1": 703, "x2": 412, "y2": 803, "rot": 0}
},
"tags": []
}
}
relations
# Threshold comparisons: all driven by ramp
connect(ramp.y, gt_thresh.u) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": -2},
{"S": -2, "M": [], "E": 2}
],
"junctions": [{"x": 140, "y": 1250}, {"x": 140, "y": 1030}],
"renderStyle": "standard"
}
}
connect(ramp.y, ge_thresh.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 1150}],
"renderStyle": "standard"
}
}
connect(ramp.y, lt_thresh.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 910}],
"renderStyle": "standard"
}
}
connect(ramp.y, le_thresh.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 550}],
"renderStyle": "standard"
}
}
# Two-input comparisons: ramp (u1) vs const1 (u2)
connect(ramp.y, gt.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 159}],
"renderStyle": "standard"
}
}
connect(const1.y, gt.u2) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": -2},
{"S": -2, "M": [], "E": 2}
],
"junctions": [{"x": 150, "y": 455}, {"x": 150, "y": 215}],
"renderStyle": "standard"
}
}
connect(ramp.y, ge.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 399}],
"renderStyle": "standard"
}
}
connect(const1.y, ge.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(ramp.y, lt.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 279}],
"renderStyle": "standard"
}
}
connect(const1.y, lt.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 150, "y": 455}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 150, "y": 335}],
"renderStyle": "standard"
}
}
connect(ramp.y, le.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}, {"x": 140, "y": 39}], "E": 2}],
"renderStyle": "standard"
}
}
connect(const1.y, le.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 150, "y": 455}, {"x": 150, "y": 95}], "E": 2}],
"renderStyle": "standard"
}
}
# Not: inverts GreaterThreshold
connect(gt_thresh.y, not1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
# Boolean sources for LogicalSwitch
connect(ramp.y, boolTrue.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 670}],
"renderStyle": "standard"
}
}
connect(ramp.y, boolFalse.u) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 1250}], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 140, "y": 790}],
"renderStyle": "standard"
}
}
# Switch: u2=gt_thresh controls between ramp (u1) and const10 (u3)
connect(ramp.y, sw.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(gt_thresh.y, sw.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 291, "y": 1282}], "E": 2}],
"junctions": [{"x": 291, "y": 1030}],
"renderStyle": "standard"
}
}
connect(const10.y, sw.u3) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 1351}, {"x": 291, "y": 1314}], "E": 2}],
"renderStyle": "standard"
}
}
# LogicalSwitch: u2=gt_thresh controls between boolTrue (u1) and boolFalse (u3)
connect(boolTrue.y, lsw.u1) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 670}, {"x": 291, "y": 716}], "E": 2}],
"renderStyle": "standard"
}
}
connect(gt_thresh.y, lsw.u2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 291, "y": 1030}, {"x": 291, "y": 753}], "E": 2}],
"renderStyle": "standard"
}
}
connect(boolFalse.y, lsw.u3) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"below": {
"stop": 1,
"params": {"ramp.offset": -2},
"expect": {
"signals": [
"ramp.y",
"gt_thresh.y",
"ge_thresh.y",
"lt_thresh.y",
"le_thresh.y",
"gt.y",
"ge.y",
"lt.y",
"le.y",
"not1.y",
"sw.y",
"lsw.y"
]
}
},
"equal": {
"stop": 1,
"params": {"ramp.offset": 0},
"expect": {
"signals": [
"ramp.y",
"gt_thresh.y",
"ge_thresh.y",
"lt_thresh.y",
"le_thresh.y",
"gt.y",
"ge.y",
"lt.y",
"le.y",
"not1.y",
"sw.y",
"lsw.y"
]
}
},
"above": {
"stop": 1,
"params": {"ramp.offset": 1.5},
"expect": {
"signals": [
"ramp.y",
"gt_thresh.y",
"ge_thresh.y",
"lt_thresh.y",
"le_thresh.y",
"gt.y",
"ge.y",
"lt.y",
"le.y",
"not1.y",
"sw.y",
"lsw.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 below
julia
@named model_below = BlockComponents.Logical.Tests.LogicalValidation(ramp.offset=-2)
model_below = toggle_namespacing(model_below, false)
model_below = toggle_namespacing(model_below, true)
result_below = TransientAnalysis(; model = model_below, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_below = rebuild_sol(result_below)<< @setup-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.ramp.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.ramp.y], width=2, label="Actual value of ramp.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of ramp.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.gt_thresh.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.gt_thresh.y], width=2, label="Actual value of gt_thresh.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of gt_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.ge_thresh.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.ge_thresh.y], width=2, label="Actual value of ge_thresh.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of ge_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.lt_thresh.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.lt_thresh.y], width=2, label="Actual value of lt_thresh.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of lt_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.le_thresh.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.le_thresh.y], width=2, label="Actual value of le_thresh.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of le_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.gt.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.gt.y], width=2, label="Actual value of gt.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of gt.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.ge.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.ge.y], width=2, label="Actual value of ge.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of ge.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.lt.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig7.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.lt.y], width=2, label="Actual value of lt.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of lt.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.le.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig8.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.le.y], width=2, label="Actual value of le.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of le.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.not1.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig9.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.not1.y], width=2, label="Actual value of not1.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of not1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.sw.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig10.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.sw.y], width=2, label="Actual value of sw.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of sw.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_below = DataFrame(:t => sol_below[:t], :actual => sol_below[model_below.lsw.y])
dfr_below = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_below_sig11.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_below, idxs=[model_below.lsw.y], width=2, label="Actual value of lsw.y")
if !isnothing(dfr_below)
scatter!(plt, dfr_below.t, dfr_below.expected, mc=:red, ms=3, label="Expected value of lsw.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>Test Case equal
julia
@named model_equal = BlockComponents.Logical.Tests.LogicalValidation(ramp.offset=0)
model_equal = toggle_namespacing(model_equal, false)
model_equal = toggle_namespacing(model_equal, true)
result_equal = TransientAnalysis(; model = model_equal, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_equal = rebuild_sol(result_equal)<< @setup-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.ramp.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.ramp.y], width=2, label="Actual value of ramp.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of ramp.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.gt_thresh.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.gt_thresh.y], width=2, label="Actual value of gt_thresh.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of gt_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.ge_thresh.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.ge_thresh.y], width=2, label="Actual value of ge_thresh.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of ge_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.lt_thresh.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.lt_thresh.y], width=2, label="Actual value of lt_thresh.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of lt_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.le_thresh.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.le_thresh.y], width=2, label="Actual value of le_thresh.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of le_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.gt.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.gt.y], width=2, label="Actual value of gt.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of gt.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.ge.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.ge.y], width=2, label="Actual value of ge.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of ge.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.lt.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig7.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.lt.y], width=2, label="Actual value of lt.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of lt.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.le.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig8.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.le.y], width=2, label="Actual value of le.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of le.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.not1.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig9.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.not1.y], width=2, label="Actual value of not1.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of not1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.sw.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig10.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.sw.y], width=2, label="Actual value of sw.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of sw.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_equal = DataFrame(:t => sol_equal[:t], :actual => sol_equal[model_equal.lsw.y])
dfr_equal = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_equal_sig11.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_equal, idxs=[model_equal.lsw.y], width=2, label="Actual value of lsw.y")
if !isnothing(dfr_equal)
scatter!(plt, dfr_equal.t, dfr_equal.expected, mc=:red, ms=3, label="Expected value of lsw.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>Test Case above
julia
@named model_above = BlockComponents.Logical.Tests.LogicalValidation(ramp.offset=1.5)
model_above = toggle_namespacing(model_above, false)
model_above = toggle_namespacing(model_above, true)
result_above = TransientAnalysis(; model = model_above, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+0, abstol=1e-6, reltol=1e-6)
sol_above = rebuild_sol(result_above)<< @setup-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.ramp.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.ramp.y], width=2, label="Actual value of ramp.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of ramp.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.gt_thresh.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.gt_thresh.y], width=2, label="Actual value of gt_thresh.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of gt_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.ge_thresh.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.ge_thresh.y], width=2, label="Actual value of ge_thresh.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of ge_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.lt_thresh.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.lt_thresh.y], width=2, label="Actual value of lt_thresh.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of lt_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.le_thresh.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.le_thresh.y], width=2, label="Actual value of le_thresh.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of le_thresh.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.gt.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig5.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.gt.y], width=2, label="Actual value of gt.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of gt.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.ge.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig6.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.ge.y], width=2, label="Actual value of ge.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of ge.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.lt.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig7.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.lt.y], width=2, label="Actual value of lt.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of lt.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.le.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig8.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.le.y], width=2, label="Actual value of le.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of le.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.not1.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig9.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.not1.y], width=2, label="Actual value of not1.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of not1.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.sw.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig10.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.sw.y], width=2, label="Actual value of sw.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of sw.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>julia
df_above = DataFrame(:t => sol_above[:t], :actual => sol_above[model_above.lsw.y])
dfr_above = try CSV.read(joinpath(snapshotsdir, "BlockComponents.Logical.Tests.LogicalValidation_above_sig11.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_above, idxs=[model_above.lsw.y], width=2, label="Actual value of lsw.y")
if !isnothing(dfr_above)
scatter!(plt, dfr_above.t, dfr_above.expected, mc=:red, ms=3, label="Expected value of lsw.y")
end<< @setup-block not executed in draft mode >>julia
plt<< @example-block not executed in draft mode >>