fmdtools-AdaStress integration

NOTE: This notebook may not run correctly, see ticket RAD-224

This goal of this notebook is to illustrate running Adaptive Stress Testing on fmdtools model using the AdaStress package.

For this setup to work, first install: - AdaStress (and related packages) in Julia - fmdtools (and related packages) in Python - PyCall in Julia - - Make sure ENV[“PYTHON”] points to python kernel where fmdtools is installed - PyJulia in Python

[1]:
# Commands for building PyCall where python is located:
# ENV["PYTHON"] = "C:\\Users\\dhulse\\AppData\\Local\\anaconda3\\python.exe"
# using Pkg
# Pkg.build("PyCall")
[2]:
using Plots
using AdaStress

Python setup:

First, we get the fmdtools model from its respective folder

[3]:

using PyCall #ENV["MPLBACKEND"]="qt5agg" using PyPlot py""" import sys, os sys.path.insert(0,os.curdir) sys.path.insert(1,os.path.join('..')) """
[4]:
PyCall.pyversion
[4]:
v"3.10.9"
[5]:
#pygui_start(:qt)
#PyCall.fixqtpath()

Next, we get the module–in this case we will be using the stochastic pump model in /example_pump/pump_stochastic

[6]:
pump_module = pyimport("pump_stochastic")
pump_model = pump_module.Pump(p = Dict("delay" => 1.0))
pump_model.p
[6]:
PyObject PumpParam(cost=('repair', 'water'), delay=1)

To get the propagation/analysis methods, we can further import the fmdtools packages…

[7]:
fmd = pyimport("fmdtools")
prop = fmd.sim.propagate
an = fmd.analyze
[7]:
PyObject <module 'fmdtools.analyze' from 'c:\\users\\dhulse\\documents\\github\\fmdtools\\fmdtools\\analyze\\__init__.py'>

Example simulation

[8]:
endresult, mdlhist = prop.nominal(pump_model, run_stochastic=true);

NOTE: in order for Result.plot_line to work correctly, make sure to use the Using PyCall command at the beginning.

[9]:
fig, axs = mdlhist.plot_line("fxns.move_water.s.eff",
                                 "fxns.move_water.s.total_flow",
                                 "flows.wat_2.s.flowrate",
                                 "flows.wat_2.s.pressure")
../../_images/examples_pump_AST_Sampling_14_0.png
[9]:
(Figure(PyObject <Figure size 600x400 with 4 Axes>), PyObject[PyObject <Axes: title={'center': 'fxns.move_water.s.eff'}, xlabel=' '>, PyObject <Axes: title={'center': 'fxns.move_water.s.total_flow'}, xlabel=' '>, PyObject <Axes: title={'center': 'flows.wat_2.s.flowrate'}, xlabel='time'>, PyObject <Axes: title={'center': 'flows.wat_2.s.pressure'}, xlabel='time'>])

AdaStress Setup

Interfacing AdaStress with fmdtools models is enabled by the DynamicProblem class in sim.search (though this can also be done manually). See below.

[10]:
DynamicProblem = fmd.sim.search.DynamicInterface
[10]:
PyObject <class 'fmdtools.sim.search.DynamicInterface'>
[11]:
prob = DynamicProblem(pump_model)
[11]:
PyObject <fmdtools.sim.search.DynamicInterface object at 0x000001FBEA47D7B0>

Defining the simulation is quite simple with the DynamicProblem class. Note the possible options from this class

[12]:
?DynamicProblem.__init__
[12]:

        Initialize the problem.

        Parameters
        ----------
        mdl : Model
            Model defining the simulation.
        mdl_kwargs : dict, optional
            Parameters to run the model at. The default is {}.
        t_max : float, optional
            Maximum simulation time. The default is False.
        track : str/dict, optional
            Properties of the model to track over time. The default is "all".
        run_stochastic : bool/str, optional
            Whether to run stochastic behaviors (True/False) and/or
            return pdf ("track_pdf"). The default is "track_pdf".
        desired_result : list, optional
            List of desired results to return at each update. The default is [].
        use_end_condition : bool, optional
            Whether to use model end-condition. The default is None.

[13]:
Base.@kwdef mutable struct PumpSim <: AdaStress.BlackBox
    sim::PyObject = DynamicProblem(pump_model)
end
[13]:
PumpSim
[14]:
function initialize!(sim::PumpSim)
    sim.sim = DynamicProblem(pump_model)
end
[14]:
initialize! (generic function with 1 method)

Updating is further enabled by DynamicProblem.update

[15]:
?DynamicProblem.update
[15]:

        Update the model states at the simulation time and iterates time.

        Parameters
        ----------
        seed : seed, optional
            Seed for the simulation. The default is {}.
        faults : dict, optional
            faults to inject in the model, with structure {fxn:[faults]}.
            The default is {}.
        disturbances : dict, optional
            Variables to change in the model, with structure {fxn.var:value}.
            The default is {}.

        Returns
        -------
        returns : dict
            dictionary of returns with values corresponding to desired_result

[16]:
function update!(sim::PumpSim)
    seed = rand(0:1_000_000_000)
    returns = sim.sim.update(seed=seed)
    return log(returns["pdf"]) # note: needs to return a probability from somewhere - needs to be a log pdf?
end
[16]:
update! (generic function with 1 method)

Model end-states can be interfaced with using DynamicProblem.check_sim_end, which additionally accomodates external conditions.

[17]:
function isterminal!(sim::PumpSim)
    has_faults = sim.sim.mdl.fxns["move_water"].m.any_faults() # our external condition
    terminal = sim.sim.check_sim_end(external_condition=has_faults)
    return terminal
end
[17]:
isterminal! (generic function with 1 method)
[18]:
function isevent!(sim::PumpSim)
    faults = sim.sim.mdl.fxns["move_water"].m.any_faults()
    return faults
end
[18]:
isevent! (generic function with 1 method)

Finally, the below shows the full setup:

[19]:
AdaStress.reset!(sim::PumpSim) = initialize!(sim)
AdaStress.step!(sim::PumpSim) = update!(sim)
AdaStress.isterminal(sim::PumpSim) = isterminal!(sim)
AdaStress.isevent(sim::PumpSim) = isevent!(sim)     # difficult: get pressure > 15 ten times
# AdaStress.isevent(sim::PumpSim) = 15.0-sim.mdl.flows["Wat_1"].pressure <= 0 # - easy: just get pressure > 15 (once!)
#AdaStress.distance(sim::PumpSim) = 15.0-sim.mdl.flows["Wat_1"].pressure
AdaStress.distance(sim::PumpSim) = float(sum(sim.sim.mdl.h.flows.wat_1.s.pressure.<=15))

Running AdaStress Methods

Monte Carlo Search

[69]:
mcs = AdaStress.Solvers.MCS(num_iterations=10_00)
[69]:
AdaStress.Solvers.MonteCarloSearch.MCS(1000, 10)
[70]:
mdp = AdaStress.ASTMDP(PumpSim())
mdp.reward.event_bonus = 200.0
[70]:
200.0
[71]:
using Random
[72]:
Random.seed!(0)
sol = mcs(() -> mdp)
Progress: 100%|█████████████████████████████████████████| Time: 0:00:37
[72]:
DataStructures.PriorityQueue{Any, Any, Base.Order.ForwardOrdering} with 10 entries:
  MCSResult(UInt32[0x20a6d935, 0x28bba493, 0xb7b93759, 0xd1a1446c, 0… => 206.991
  MCSResult(UInt32[0x084541d7, 0x84540de9, 0x7cc282fe, 0x8c04197f, 0… => 207.019
  MCSResult(UInt32[0x13ad911b, 0xf09a855d, 0x47101ea7, 0x25d57373, 0… => 208.057
  MCSResult(UInt32[0xef54ffaf, 0x5b752e2b, 0x8940f9fe, 0x87bfa056])   => 208.121
  MCSResult(UInt32[0xa4fdc8b9, 0xbc7ce3e9, 0x1d17d64d, 0xc72e51ab, 0… => 208.256
  MCSResult(UInt32[0xfb1a01a1, 0x45b42a6c, 0xdea6badb, 0x49b2b636, 0… => 209.586
  MCSResult(UInt32[0x10c6c90c, 0xb0192166, 0xd7c40237, 0x6b827ac9, 0… => 210.216
  MCSResult(UInt32[0x1c031724, 0x22bca5ad, 0xec5453ee, 0x38a2c995, 0… => 210.228
  MCSResult(UInt32[0x769c9150, 0x211f39ca, 0x8b28f979, 0xb16ab1f2, 0… => 211.552
  MCSResult(UInt32[0x3ab41a82, 0xcd4d763d, 0x219e185b, 0xca868fbb, 0… => 213.017
[73]:
i=0
mdlhists = Dict()
for (result, r) in sol
    AdaStress.replay!(mdp, result)
    mdlhists[string("scen", i)] = mdp.sim.sim.hist
    i+=1
end
mdlhists = fmd.analyze.history.History(mdlhists)
mdlhists = mdlhists.flatten()
[73]:
PyObject scen1.i.finished:              array(56)
scen1.i.on:                    array(56)
scen1.r.probdens:              array(56)
scen1.flows.ee_1.s.current:    array(56)
scen1.flows.ee_1.s.voltage:    array(56)
scen1.flows.sig_1.s.power:     array(56)
scen1.flows.wat_1.s.flowrate:  array(56)
scen1.flows.wat_1.s.pressure:  array(56)
scen1.flows.wat_1.s.area:      array(56)
scen1.flows.wat_1.s.level:     array(56)
scen1.flows.wat_2.s.flowrate:  array(56)
scen1.flows.wat_2.s.pressure:  array(56)
scen1.flows.wat_2.s.area:      array(56)
scen1.flows.wat_2.s.level:     array(56)
scen1.fxns.import_ee.s.effstate: array(56)
scen1.fxns.import_ee.m.faults.no_v: array(56)
scen1.fxns.import_ee.m.faults.inf_v: array(56)
scen1.fxns.import_ee.r.s.effstate: array(56)
scen1.fxns.import_ee.r.s.grid_noise: array(56)
scen1.fxns.import_ee.r.probdens: array(56)
scen1.fxns.import_wa           array(56)
scen1.fxns.import_wa           array(56)
scen1.fxns.import_si           array(56)
scen1.fxns.import_signal.r.s.sig_noise: array(56)
scen1.fxns.import_signal.r.probdens: array(56)
scen1.fxns.move_water.i.over_pressure: array(56)
scen1.fxns.move_water.s.total_flow: array(56)
scen1.fxns.move_water.s.eff:   array(56)
scen1.fxns.move_wate           array(56)
scen1.fxns.move_water.m.faults.short: array(56)
scen1.fxns.move_water.r.s.eff: array(56)
scen1.fxns.move_water.r.probdens: array(56)
scen1.fxns.move_wate           array(56)
scen1.fxns.move_wate           array(56)
scen1.fxns.export_water.m.faults.block: array(56)
scen1.time:                    array(56)
scen5.i.finished:              array(56)
scen5.i.on:                    array(56)
scen5.r.probdens:              array(56)
scen5.flows.ee_1.s.current:    array(56)
scen5.flows.ee_1.s.voltage:    array(56)
scen5.flows.sig_1.s.power:     array(56)
scen5.flows.wat_1.s.flowrate:  array(56)
scen5.flows.wat_1.s.pressure:  array(56)
scen5.flows.wat_1.s.area:      array(56)
scen5.flows.wat_1.s.level:     array(56)
scen5.flows.wat_2.s.flowrate:  array(56)
scen5.flows.wat_2.s.pressure:  array(56)
scen5.flows.wat_2.s.area:      array(56)
scen5.flows.wat_2.s.level:     array(56)
scen5.fxns.import_ee.s.effstate: array(56)
scen5.fxns.import_ee.m.faults.no_v: array(56)
scen5.fxns.import_ee.m.faults.inf_v: array(56)
scen5.fxns.import_ee.r.s.effstate: array(56)
scen5.fxns.import_ee.r.s.grid_noise: array(56)
scen5.fxns.import_ee.r.probdens: array(56)
scen5.fxns.import_wa           array(56)
scen5.fxns.import_wa           array(56)
scen5.fxns.import_si           array(56)
scen5.fxns.import_signal.r.s.sig_noise: array(56)
scen5.fxns.import_signal.r.probdens: array(56)
scen5.fxns.move_water.i.over_pressure: array(56)
scen5.fxns.move_water.s.total_flow: array(56)
scen5.fxns.move_water.s.eff:   array(56)
scen5.fxns.move_wate           array(56)
scen5.fxns.move_water.m.faults.short: array(56)
scen5.fxns.move_water.r.s.eff: array(56)
scen5.fxns.move_water.r.probdens: array(56)
scen5.fxns.move_wate           array(56)
scen5.fxns.move_wate           array(56)
scen5.fxns.export_water.m.faults.block: array(56)
scen5.time:                    array(56)
scen6.i.finished:              array(56)
scen6.i.on:                    array(56)
scen6.r.probdens:              array(56)
scen6.flows.ee_1.s.current:    array(56)
scen6.flows.ee_1.s.voltage:    array(56)
scen6.flows.sig_1.s.power:     array(56)
scen6.flows.wat_1.s.flowrate:  array(56)
scen6.flows.wat_1.s.pressure:  array(56)
scen6.flows.wat_1.s.area:      array(56)
scen6.flows.wat_1.s.level:     array(56)
scen6.flows.wat_2.s.flowrate:  array(56)
scen6.flows.wat_2.s.pressure:  array(56)
scen6.flows.wat_2.s.area:      array(56)
scen6.flows.wat_2.s.level:     array(56)
scen6.fxns.import_ee.s.effstate: array(56)
scen6.fxns.import_ee.m.faults.no_v: array(56)
scen6.fxns.import_ee.m.faults.inf_v: array(56)
scen6.fxns.import_ee.r.s.effstate: array(56)
scen6.fxns.import_ee.r.s.grid_noise: array(56)
scen6.fxns.import_ee.r.probdens: array(56)
scen6.fxns.import_wa           array(56)
scen6.fxns.import_wa           array(56)
scen6.fxns.import_si           array(56)
scen6.fxns.import_signal.r.s.sig_noise: array(56)
scen6.fxns.import_signal.r.probdens: array(56)
scen6.fxns.move_water.i.over_pressure: array(56)
scen6.fxns.move_water.s.total_flow: array(56)
scen6.fxns.move_water.s.eff:   array(56)
scen6.fxns.move_wate           array(56)
scen6.fxns.move_water.m.faults.short: array(56)
scen6.fxns.move_water.r.s.eff: array(56)
scen6.fxns.move_water.r.probdens: array(56)
scen6.fxns.move_wate           array(56)
scen6.fxns.move_wate           array(56)
scen6.fxns.export_water.m.faults.block: array(56)
scen6.time:                    array(56)
scen3.i.finished:              array(56)
scen3.i.on:                    array(56)
scen3.r.probdens:              array(56)
scen3.flows.ee_1.s.current:    array(56)
scen3.flows.ee_1.s.voltage:    array(56)
scen3.flows.sig_1.s.power:     array(56)
scen3.flows.wat_1.s.flowrate:  array(56)
scen3.flows.wat_1.s.pressure:  array(56)
scen3.flows.wat_1.s.area:      array(56)
scen3.flows.wat_1.s.level:     array(56)
scen3.flows.wat_2.s.flowrate:  array(56)
scen3.flows.wat_2.s.pressure:  array(56)
scen3.flows.wat_2.s.area:      array(56)
scen3.flows.wat_2.s.level:     array(56)
scen3.fxns.import_ee.s.effstate: array(56)
scen3.fxns.import_ee.m.faults.no_v: array(56)
scen3.fxns.import_ee.m.faults.inf_v: array(56)
scen3.fxns.import_ee.r.s.effstate: array(56)
scen3.fxns.import_ee.r.s.grid_noise: array(56)
scen3.fxns.import_ee.r.probdens: array(56)
scen3.fxns.import_wa           array(56)
scen3.fxns.import_wa           array(56)
scen3.fxns.import_si           array(56)
scen3.fxns.import_signal.r.s.sig_noise: array(56)
scen3.fxns.import_signal.r.probdens: array(56)
scen3.fxns.move_water.i.over_pressure: array(56)
scen3.fxns.move_water.s.total_flow: array(56)
scen3.fxns.move_water.s.eff:   array(56)
scen3.fxns.move_wate           array(56)
scen3.fxns.move_water.m.faults.short: array(56)
scen3.fxns.move_water.r.s.eff: array(56)
scen3.fxns.move_water.r.probdens: array(56)
scen3.fxns.move_wate           array(56)
scen3.fxns.move_wate           array(56)
scen3.fxns.export_water.m.faults.block: array(56)
scen3.time:                    array(56)
scen4.i.finished:              array(56)
scen4.i.on:                    array(56)
scen4.r.probdens:              array(56)
scen4.flows.ee_1.s.current:    array(56)
scen4.flows.ee_1.s.voltage:    array(56)
scen4.flows.sig_1.s.power:     array(56)
scen4.flows.wat_1.s.flowrate:  array(56)
scen4.flows.wat_1.s.pressure:  array(56)
scen4.flows.wat_1.s.area:      array(56)
scen4.flows.wat_1.s.level:     array(56)
scen4.flows.wat_2.s.flowrate:  array(56)
scen4.flows.wat_2.s.pressure:  array(56)
scen4.flows.wat_2.s.area:      array(56)
scen4.flows.wat_2.s.level:     array(56)
scen4.fxns.import_ee.s.effstate: array(56)
scen4.fxns.import_ee.m.faults.no_v: array(56)
scen4.fxns.import_ee.m.faults.inf_v: array(56)
scen4.fxns.import_ee.r.s.effstate: array(56)
scen4.fxns.import_ee.r.s.grid_noise: array(56)
scen4.fxns.import_ee.r.probdens: array(56)
scen4.fxns.import_wa           array(56)
scen4.fxns.import_wa           array(56)
scen4.fxns.import_si           array(56)
scen4.fxns.import_signal.r.s.sig_noise: array(56)
scen4.fxns.import_signal.r.probdens: array(56)
scen4.fxns.move_water.i.over_pressure: array(56)
scen4.fxns.move_water.s.total_flow: array(56)
scen4.fxns.move_water.s.eff:   array(56)
scen4.fxns.move_wate           array(56)
scen4.fxns.move_water.m.faults.short: array(56)
scen4.fxns.move_water.r.s.eff: array(56)
scen4.fxns.move_water.r.probdens: array(56)
scen4.fxns.move_wate           array(56)
scen4.fxns.move_wate           array(56)
scen4.fxns.export_water.m.faults.block: array(56)
scen4.time:                    array(56)
scen0.i.finished:              array(56)
scen0.i.on:                    array(56)
scen0.r.probdens:              array(56)
scen0.flows.ee_1.s.current:    array(56)
scen0.flows.ee_1.s.voltage:    array(56)
scen0.flows.sig_1.s.power:     array(56)
scen0.flows.wat_1.s.flowrate:  array(56)
scen0.flows.wat_1.s.pressure:  array(56)
scen0.flows.wat_1.s.area:      array(56)
scen0.flows.wat_1.s.level:     array(56)
scen0.flows.wat_2.s.flowrate:  array(56)
scen0.flows.wat_2.s.pressure:  array(56)
scen0.flows.wat_2.s.area:      array(56)
scen0.flows.wat_2.s.level:     array(56)
scen0.fxns.import_ee.s.effstate: array(56)
scen0.fxns.import_ee.m.faults.no_v: array(56)
scen0.fxns.import_ee.m.faults.inf_v: array(56)
scen0.fxns.import_ee.r.s.effstate: array(56)
scen0.fxns.import_ee.r.s.grid_noise: array(56)
scen0.fxns.import_ee.r.probdens: array(56)
scen0.fxns.import_wa           array(56)
scen0.fxns.import_wa           array(56)
scen0.fxns.import_si           array(56)
scen0.fxns.import_signal.r.s.sig_noise: array(56)
scen0.fxns.import_signal.r.probdens: array(56)
scen0.fxns.move_water.i.over_pressure: array(56)
scen0.fxns.move_water.s.total_flow: array(56)
scen0.fxns.move_water.s.eff:   array(56)
scen0.fxns.move_wate           array(56)
scen0.fxns.move_water.m.faults.short: array(56)
scen0.fxns.move_water.r.s.eff: array(56)
scen0.fxns.move_water.r.probdens: array(56)
scen0.fxns.move_wate           array(56)
scen0.fxns.move_wate           array(56)
scen0.fxns.export_water.m.faults.block: array(56)
scen0.time:                    array(56)
scen2.i.finished:              array(56)
scen2.i.on:                    array(56)
scen2.r.probdens:              array(56)
scen2.flows.ee_1.s.current:    array(56)
scen2.flows.ee_1.s.voltage:    array(56)
scen2.flows.sig_1.s.power:     array(56)
scen2.flows.wat_1.s.flowrate:  array(56)
scen2.flows.wat_1.s.pressure:  array(56)
scen2.flows.wat_1.s.area:      array(56)
scen2.flows.wat_1.s.level:     array(56)
scen2.flows.wat_2.s.flowrate:  array(56)
scen2.flows.wat_2.s.pressure:  array(56)
scen2.flows.wat_2.s.area:      array(56)
scen2.flows.wat_2.s.level:     array(56)
scen2.fxns.import_ee.s.effstate: array(56)
scen2.fxns.import_ee.m.faults.no_v: array(56)
scen2.fxns.import_ee.m.faults.inf_v: array(56)
scen2.fxns.import_ee.r.s.effstate: array(56)
scen2.fxns.import_ee.r.s.grid_noise: array(56)
scen2.fxns.import_ee.r.probdens: array(56)
scen2.fxns.import_wa           array(56)
scen2.fxns.import_wa           array(56)
scen2.fxns.import_si           array(56)
scen2.fxns.import_signal.r.s.sig_noise: array(56)
scen2.fxns.import_signal.r.probdens: array(56)
scen2.fxns.move_water.i.over_pressure: array(56)
scen2.fxns.move_water.s.total_flow: array(56)
scen2.fxns.move_water.s.eff:   array(56)
scen2.fxns.move_wate           array(56)
scen2.fxns.move_water.m.faults.short: array(56)
scen2.fxns.move_water.r.s.eff: array(56)
scen2.fxns.move_water.r.probdens: array(56)
scen2.fxns.move_wate           array(56)
scen2.fxns.move_wate           array(56)
scen2.fxns.export_water.m.faults.block: array(56)
scen2.time:                    array(56)
scen9.i.finished:              array(56)
scen9.i.on:                    array(56)
scen9.r.probdens:              array(56)
scen9.flows.ee_1.s.current:    array(56)
scen9.flows.ee_1.s.voltage:    array(56)
scen9.flows.sig_1.s.power:     array(56)
scen9.flows.wat_1.s.flowrate:  array(56)
scen9.flows.wat_1.s.pressure:  array(56)
scen9.flows.wat_1.s.area:      array(56)
scen9.flows.wat_1.s.level:     array(56)
scen9.flows.wat_2.s.flowrate:  array(56)
scen9.flows.wat_2.s.pressure:  array(56)
scen9.flows.wat_2.s.area:      array(56)
scen9.flows.wat_2.s.level:     array(56)
scen9.fxns.import_ee.s.effstate: array(56)
scen9.fxns.import_ee.m.faults.no_v: array(56)
scen9.fxns.import_ee.m.faults.inf_v: array(56)
scen9.fxns.import_ee.r.s.effstate: array(56)
scen9.fxns.import_ee.r.s.grid_noise: array(56)
scen9.fxns.import_ee.r.probdens: array(56)
scen9.fxns.import_wa           array(56)
scen9.fxns.import_wa           array(56)
scen9.fxns.import_si           array(56)
scen9.fxns.import_signal.r.s.sig_noise: array(56)
scen9.fxns.import_signal.r.probdens: array(56)
scen9.fxns.move_water.i.over_pressure: array(56)
scen9.fxns.move_water.s.total_flow: array(56)
scen9.fxns.move_water.s.eff:   array(56)
scen9.fxns.move_wate           array(56)
scen9.fxns.move_water.m.faults.short: array(56)
scen9.fxns.move_water.r.s.eff: array(56)
scen9.fxns.move_water.r.probdens: array(56)
scen9.fxns.move_wate           array(56)
scen9.fxns.move_wate           array(56)
scen9.fxns.export_water.m.faults.block: array(56)
scen9.time:                    array(56)
scen8.i.finished:              array(56)
scen8.i.on:                    array(56)
scen8.r.probdens:              array(56)
scen8.flows.ee_1.s.current:    array(56)
scen8.flows.ee_1.s.voltage:    array(56)
scen8.flows.sig_1.s.power:     array(56)
scen8.flows.wat_1.s.flowrate:  array(56)
scen8.flows.wat_1.s.pressure:  array(56)
scen8.flows.wat_1.s.area:      array(56)
scen8.flows.wat_1.s.level:     array(56)
scen8.flows.wat_2.s.flowrate:  array(56)
scen8.flows.wat_2.s.pressure:  array(56)
scen8.flows.wat_2.s.area:      array(56)
scen8.flows.wat_2.s.level:     array(56)
scen8.fxns.import_ee.s.effstate: array(56)
scen8.fxns.import_ee.m.faults.no_v: array(56)
scen8.fxns.import_ee.m.faults.inf_v: array(56)
scen8.fxns.import_ee.r.s.effstate: array(56)
scen8.fxns.import_ee.r.s.grid_noise: array(56)
scen8.fxns.import_ee.r.probdens: array(56)
scen8.fxns.import_wa           array(56)
scen8.fxns.import_wa           array(56)
scen8.fxns.import_si           array(56)
scen8.fxns.import_signal.r.s.sig_noise: array(56)
scen8.fxns.import_signal.r.probdens: array(56)
scen8.fxns.move_water.i.over_pressure: array(56)
scen8.fxns.move_water.s.total_flow: array(56)
scen8.fxns.move_water.s.eff:   array(56)
scen8.fxns.move_wate           array(56)
scen8.fxns.move_water.m.faults.short: array(56)
scen8.fxns.move_water.r.s.eff: array(56)
scen8.fxns.move_water.r.probdens: array(56)
scen8.fxns.move_wate           array(56)
scen8.fxns.move_wate           array(56)
scen8.fxns.export_water.m.faults.block: array(56)
scen8.time:                    array(56)
scen7.i.finished:              array(56)
scen7.i.on:                    array(56)
scen7.r.probdens:              array(56)
scen7.flows.ee_1.s.current:    array(56)
scen7.flows.ee_1.s.voltage:    array(56)
scen7.flows.sig_1.s.power:     array(56)
scen7.flows.wat_1.s.flowrate:  array(56)
scen7.flows.wat_1.s.pressure:  array(56)
scen7.flows.wat_1.s.area:      array(56)
scen7.flows.wat_1.s.level:     array(56)
scen7.flows.wat_2.s.flowrate:  array(56)
scen7.flows.wat_2.s.pressure:  array(56)
scen7.flows.wat_2.s.area:      array(56)
scen7.flows.wat_2.s.level:     array(56)
scen7.fxns.import_ee.s.effstate: array(56)
scen7.fxns.import_ee.m.faults.no_v: array(56)
scen7.fxns.import_ee.m.faults.inf_v: array(56)
scen7.fxns.import_ee.r.s.effstate: array(56)
scen7.fxns.import_ee.r.s.grid_noise: array(56)
scen7.fxns.import_ee.r.probdens: array(56)
scen7.fxns.import_wa           array(56)
scen7.fxns.import_wa           array(56)
scen7.fxns.import_si           array(56)
scen7.fxns.import_signal.r.s.sig_noise: array(56)
scen7.fxns.import_signal.r.probdens: array(56)
scen7.fxns.move_water.i.over_pressure: array(56)
scen7.fxns.move_water.s.total_flow: array(56)
scen7.fxns.move_water.s.eff:   array(56)
scen7.fxns.move_wate           array(56)
scen7.fxns.move_water.m.faults.short: array(56)
scen7.fxns.move_water.r.s.eff: array(56)
scen7.fxns.move_water.r.probdens: array(56)
scen7.fxns.move_wate           array(56)
scen7.fxns.move_wate           array(56)
scen7.fxns.export_water.m.faults.block: array(56)
scen7.time:                    array(56)
[74]:
mdlhists.plot_line("fxns.move_water.s.eff",
                        "fxns.move_water.s.total_flow",
                        "flows.wat_2.s.flowrate",
                        "flows.wat_2.s.pressure")
../../_images/examples_pump_AST_Sampling_36_0.png
[74]:
(Figure(PyObject <Figure size 600x400 with 4 Axes>), PyObject[PyObject <Axes: title={'center': 'fxns.move_water.s.eff'}, xlabel=' '>, PyObject <Axes: title={'center': 'fxns.move_water.s.total_flow'}, xlabel=' '>, PyObject <Axes: title={'center': 'flows.wat_2.s.flowrate'}, xlabel='time'>, PyObject <Axes: title={'center': 'flows.wat_2.s.pressure'}, xlabel='time'>])

MCTS

Monte Carlo Tree Search

[27]:
mcts = AdaStress.Solvers.MCTS(num_iterations=1000)
[27]:
AdaStress.Solvers.MonteCarloTreeSearch.MCTS(1000, 10, 1.0, 0.7, 1.0, nothing)
[28]:
Random.seed!(0)
@time sol = mcts(() -> mdp)
Progress: 100%|█████████████████████████████████████████| Time: 0:00:14
 14.751713 seconds (5.93 M allocations: 283.844 MiB, 0.48% gc time, 2.24% compilation time)
[28]:
DataStructures.PriorityQueue{Any, Any, Base.Order.ForwardOrdering} with 10 entries:
  MCTSResult(UInt32[0x828d83bf, 0x569a8b4b, 0x42db7247, 0x860d2412])  => 203.112
  MCTSResult(UInt32[0x9be7bec6, 0xa281bfa4, 0xa911ec3d])              => 203.12
  MCTSResult(UInt32[0x9be7bec6, 0xd34fd93a, 0x6bc04b0b])              => 203.151
  MCTSResult(UInt32[0xfd5b9189, 0xe6ed8348, 0x53813216])              => 203.248
  MCTSResult(UInt32[0x77d94185, 0x0593823c, 0xe2a9136a, 0x16e247bc, … => 203.706
  MCTSResult(UInt32[0x48cea00e, 0x5e5903be, 0x40184882, 0x11abadd6, … => 204.454
  MCTSResult(UInt32[0xe04f8a60, 0xff8d3670, 0x5846f74e, 0xd2c176d0, … => 204.516
  MCTSResult(UInt32[0x76bdd112, 0x40fc08c9, 0x7151eb1c, 0x25a0e9a5, … => 204.932
  MCTSResult(UInt32[0xc72f45c9, 0x2a4519ab, 0x52413abb])              => 205.292
  MCTSResult(UInt32[0x57387aea, 0xaf5383c3, 0x43d34d08, 0x1720253e, … => 206.777
[29]:
i=0
mdlhists2 = Dict()
for (result, r) in sol
    AdaStress.replay!(mdp, result)
    mdlhists2[i] = mdp.sim.sim.hist
    i+=1
end
mdlhists2 = fmd.analyze.history.History(mdlhists2)
mdlhists2 = mdlhists2.flatten()
[29]:
PyObject t0.i.finished:                 array(56)
t0.i.on:                       array(56)
t0.r.probdens:                 array(56)
t0.flows.ee_1.s.current:       array(56)
t0.flows.ee_1.s.voltage:       array(56)
t0.flows.sig_1.s.power:        array(56)
t0.flows.wat_1.s.flowrate:     array(56)
t0.flows.wat_1.s.pressure:     array(56)
t0.flows.wat_1.s.area:         array(56)
t0.flows.wat_1.s.level:        array(56)
t0.flows.wat_2.s.flowrate:     array(56)
t0.flows.wat_2.s.pressure:     array(56)
t0.flows.wat_2.s.area:         array(56)
t0.flows.wat_2.s.level:        array(56)
t0.fxns.import_ee.s.effstate:  array(56)
t0.fxns.import_ee.m.faults.no_v: array(56)
t0.fxns.import_ee.m.faults.inf_v: array(56)
t0.fxns.import_ee.r.s.effstate: array(56)
t0.fxns.import_ee.r.s.grid_noise: array(56)
t0.fxns.import_ee.r.probdens:  array(56)
t0.fxns.import_water.m.faults.no_wat: array(56)
t0.fxns.import_water.m.faults.less_wat: array(56)
t0.fxns.import_signal.m.faults.no_sig: array(56)
t0.fxns.import_signal.r.s.sig_noise: array(56)
t0.fxns.import_signal.r.probdens: array(56)
t0.fxns.move_water.i.over_pressure: array(56)
t0.fxns.move_water.s.total_flow: array(56)
t0.fxns.move_water.s.eff:      array(56)
t0.fxns.move_water.m.faults.mech_break: array(56)
t0.fxns.move_water.m.faults.short: array(56)
t0.fxns.move_water.r.s.eff:    array(56)
t0.fxns.move_water.r.probdens: array(56)
t0.fxns.move_water.t           array(56)
t0.fxns.move_water.t           array(56)
t0.fxns.export_water.m.faults.block: array(56)
t0.time:                       array(56)
t4.i.finished:                 array(56)
t4.i.on:                       array(56)
t4.r.probdens:                 array(56)
t4.flows.ee_1.s.current:       array(56)
t4.flows.ee_1.s.voltage:       array(56)
t4.flows.sig_1.s.power:        array(56)
t4.flows.wat_1.s.flowrate:     array(56)
t4.flows.wat_1.s.pressure:     array(56)
t4.flows.wat_1.s.area:         array(56)
t4.flows.wat_1.s.level:        array(56)
t4.flows.wat_2.s.flowrate:     array(56)
t4.flows.wat_2.s.pressure:     array(56)
t4.flows.wat_2.s.area:         array(56)
t4.flows.wat_2.s.level:        array(56)
t4.fxns.import_ee.s.effstate:  array(56)
t4.fxns.import_ee.m.faults.no_v: array(56)
t4.fxns.import_ee.m.faults.inf_v: array(56)
t4.fxns.import_ee.r.s.effstate: array(56)
t4.fxns.import_ee.r.s.grid_noise: array(56)
t4.fxns.import_ee.r.probdens:  array(56)
t4.fxns.import_water.m.faults.no_wat: array(56)
t4.fxns.import_water.m.faults.less_wat: array(56)
t4.fxns.import_signal.m.faults.no_sig: array(56)
t4.fxns.import_signal.r.s.sig_noise: array(56)
t4.fxns.import_signal.r.probdens: array(56)
t4.fxns.move_water.i.over_pressure: array(56)
t4.fxns.move_water.s.total_flow: array(56)
t4.fxns.move_water.s.eff:      array(56)
t4.fxns.move_water.m.faults.mech_break: array(56)
t4.fxns.move_water.m.faults.short: array(56)
t4.fxns.move_water.r.s.eff:    array(56)
t4.fxns.move_water.r.probdens: array(56)
t4.fxns.move_water.t           array(56)
t4.fxns.move_water.t           array(56)
t4.fxns.export_water.m.faults.block: array(56)
t4.time:                       array(56)
t5.i.finished:                 array(56)
t5.i.on:                       array(56)
t5.r.probdens:                 array(56)
t5.flows.ee_1.s.current:       array(56)
t5.flows.ee_1.s.voltage:       array(56)
t5.flows.sig_1.s.power:        array(56)
t5.flows.wat_1.s.flowrate:     array(56)
t5.flows.wat_1.s.pressure:     array(56)
t5.flows.wat_1.s.area:         array(56)
t5.flows.wat_1.s.level:        array(56)
t5.flows.wat_2.s.flowrate:     array(56)
t5.flows.wat_2.s.pressure:     array(56)
t5.flows.wat_2.s.area:         array(56)
t5.flows.wat_2.s.level:        array(56)
t5.fxns.import_ee.s.effstate:  array(56)
t5.fxns.import_ee.m.faults.no_v: array(56)
t5.fxns.import_ee.m.faults.inf_v: array(56)
t5.fxns.import_ee.r.s.effstate: array(56)
t5.fxns.import_ee.r.s.grid_noise: array(56)
t5.fxns.import_ee.r.probdens:  array(56)
t5.fxns.import_water.m.faults.no_wat: array(56)
t5.fxns.import_water.m.faults.less_wat: array(56)
t5.fxns.import_signal.m.faults.no_sig: array(56)
t5.fxns.import_signal.r.s.sig_noise: array(56)
t5.fxns.import_signal.r.probdens: array(56)
t5.fxns.move_water.i.over_pressure: array(56)
t5.fxns.move_water.s.total_flow: array(56)
t5.fxns.move_water.s.eff:      array(56)
t5.fxns.move_water.m.faults.mech_break: array(56)
t5.fxns.move_water.m.faults.short: array(56)
t5.fxns.move_water.r.s.eff:    array(56)
t5.fxns.move_water.r.probdens: array(56)
t5.fxns.move_water.t           array(56)
t5.fxns.move_water.t           array(56)
t5.fxns.export_water.m.faults.block: array(56)
t5.time:                       array(56)
t6.i.finished:                 array(56)
t6.i.on:                       array(56)
t6.r.probdens:                 array(56)
t6.flows.ee_1.s.current:       array(56)
t6.flows.ee_1.s.voltage:       array(56)
t6.flows.sig_1.s.power:        array(56)
t6.flows.wat_1.s.flowrate:     array(56)
t6.flows.wat_1.s.pressure:     array(56)
t6.flows.wat_1.s.area:         array(56)
t6.flows.wat_1.s.level:        array(56)
t6.flows.wat_2.s.flowrate:     array(56)
t6.flows.wat_2.s.pressure:     array(56)
t6.flows.wat_2.s.area:         array(56)
t6.flows.wat_2.s.level:        array(56)
t6.fxns.import_ee.s.effstate:  array(56)
t6.fxns.import_ee.m.faults.no_v: array(56)
t6.fxns.import_ee.m.faults.inf_v: array(56)
t6.fxns.import_ee.r.s.effstate: array(56)
t6.fxns.import_ee.r.s.grid_noise: array(56)
t6.fxns.import_ee.r.probdens:  array(56)
t6.fxns.import_water.m.faults.no_wat: array(56)
t6.fxns.import_water.m.faults.less_wat: array(56)
t6.fxns.import_signal.m.faults.no_sig: array(56)
t6.fxns.import_signal.r.s.sig_noise: array(56)
t6.fxns.import_signal.r.probdens: array(56)
t6.fxns.move_water.i.over_pressure: array(56)
t6.fxns.move_water.s.total_flow: array(56)
t6.fxns.move_water.s.eff:      array(56)
t6.fxns.move_water.m.faults.mech_break: array(56)
t6.fxns.move_water.m.faults.short: array(56)
t6.fxns.move_water.r.s.eff:    array(56)
t6.fxns.move_water.r.probdens: array(56)
t6.fxns.move_water.t           array(56)
t6.fxns.move_water.t           array(56)
t6.fxns.export_water.m.faults.block: array(56)
t6.time:                       array(56)
t2.i.finished:                 array(56)
t2.i.on:                       array(56)
t2.r.probdens:                 array(56)
t2.flows.ee_1.s.current:       array(56)
t2.flows.ee_1.s.voltage:       array(56)
t2.flows.sig_1.s.power:        array(56)
t2.flows.wat_1.s.flowrate:     array(56)
t2.flows.wat_1.s.pressure:     array(56)
t2.flows.wat_1.s.area:         array(56)
t2.flows.wat_1.s.level:        array(56)
t2.flows.wat_2.s.flowrate:     array(56)
t2.flows.wat_2.s.pressure:     array(56)
t2.flows.wat_2.s.area:         array(56)
t2.flows.wat_2.s.level:        array(56)
t2.fxns.import_ee.s.effstate:  array(56)
t2.fxns.import_ee.m.faults.no_v: array(56)
t2.fxns.import_ee.m.faults.inf_v: array(56)
t2.fxns.import_ee.r.s.effstate: array(56)
t2.fxns.import_ee.r.s.grid_noise: array(56)
t2.fxns.import_ee.r.probdens:  array(56)
t2.fxns.import_water.m.faults.no_wat: array(56)
t2.fxns.import_water.m.faults.less_wat: array(56)
t2.fxns.import_signal.m.faults.no_sig: array(56)
t2.fxns.import_signal.r.s.sig_noise: array(56)
t2.fxns.import_signal.r.probdens: array(56)
t2.fxns.move_water.i.over_pressure: array(56)
t2.fxns.move_water.s.total_flow: array(56)
t2.fxns.move_water.s.eff:      array(56)
t2.fxns.move_water.m.faults.mech_break: array(56)
t2.fxns.move_water.m.faults.short: array(56)
t2.fxns.move_water.r.s.eff:    array(56)
t2.fxns.move_water.r.probdens: array(56)
t2.fxns.move_water.t           array(56)
t2.fxns.move_water.t           array(56)
t2.fxns.export_water.m.faults.block: array(56)
t2.time:                       array(56)
t7.i.finished:                 array(56)
t7.i.on:                       array(56)
t7.r.probdens:                 array(56)
t7.flows.ee_1.s.current:       array(56)
t7.flows.ee_1.s.voltage:       array(56)
t7.flows.sig_1.s.power:        array(56)
t7.flows.wat_1.s.flowrate:     array(56)
t7.flows.wat_1.s.pressure:     array(56)
t7.flows.wat_1.s.area:         array(56)
t7.flows.wat_1.s.level:        array(56)
t7.flows.wat_2.s.flowrate:     array(56)
t7.flows.wat_2.s.pressure:     array(56)
t7.flows.wat_2.s.area:         array(56)
t7.flows.wat_2.s.level:        array(56)
t7.fxns.import_ee.s.effstate:  array(56)
t7.fxns.import_ee.m.faults.no_v: array(56)
t7.fxns.import_ee.m.faults.inf_v: array(56)
t7.fxns.import_ee.r.s.effstate: array(56)
t7.fxns.import_ee.r.s.grid_noise: array(56)
t7.fxns.import_ee.r.probdens:  array(56)
t7.fxns.import_water.m.faults.no_wat: array(56)
t7.fxns.import_water.m.faults.less_wat: array(56)
t7.fxns.import_signal.m.faults.no_sig: array(56)
t7.fxns.import_signal.r.s.sig_noise: array(56)
t7.fxns.import_signal.r.probdens: array(56)
t7.fxns.move_water.i.over_pressure: array(56)
t7.fxns.move_water.s.total_flow: array(56)
t7.fxns.move_water.s.eff:      array(56)
t7.fxns.move_water.m.faults.mech_break: array(56)
t7.fxns.move_water.m.faults.short: array(56)
t7.fxns.move_water.r.s.eff:    array(56)
t7.fxns.move_water.r.probdens: array(56)
t7.fxns.move_water.t           array(56)
t7.fxns.move_water.t           array(56)
t7.fxns.export_water.m.faults.block: array(56)
t7.time:                       array(56)
t9.i.finished:                 array(56)
t9.i.on:                       array(56)
t9.r.probdens:                 array(56)
t9.flows.ee_1.s.current:       array(56)
t9.flows.ee_1.s.voltage:       array(56)
t9.flows.sig_1.s.power:        array(56)
t9.flows.wat_1.s.flowrate:     array(56)
t9.flows.wat_1.s.pressure:     array(56)
t9.flows.wat_1.s.area:         array(56)
t9.flows.wat_1.s.level:        array(56)
t9.flows.wat_2.s.flowrate:     array(56)
t9.flows.wat_2.s.pressure:     array(56)
t9.flows.wat_2.s.area:         array(56)
t9.flows.wat_2.s.level:        array(56)
t9.fxns.import_ee.s.effstate:  array(56)
t9.fxns.import_ee.m.faults.no_v: array(56)
t9.fxns.import_ee.m.faults.inf_v: array(56)
t9.fxns.import_ee.r.s.effstate: array(56)
t9.fxns.import_ee.r.s.grid_noise: array(56)
t9.fxns.import_ee.r.probdens:  array(56)
t9.fxns.import_water.m.faults.no_wat: array(56)
t9.fxns.import_water.m.faults.less_wat: array(56)
t9.fxns.import_signal.m.faults.no_sig: array(56)
t9.fxns.import_signal.r.s.sig_noise: array(56)
t9.fxns.import_signal.r.probdens: array(56)
t9.fxns.move_water.i.over_pressure: array(56)
t9.fxns.move_water.s.total_flow: array(56)
t9.fxns.move_water.s.eff:      array(56)
t9.fxns.move_water.m.faults.mech_break: array(56)
t9.fxns.move_water.m.faults.short: array(56)
t9.fxns.move_water.r.s.eff:    array(56)
t9.fxns.move_water.r.probdens: array(56)
t9.fxns.move_water.t           array(56)
t9.fxns.move_water.t           array(56)
t9.fxns.export_water.m.faults.block: array(56)
t9.time:                       array(56)
t8.i.finished:                 array(56)
t8.i.on:                       array(56)
t8.r.probdens:                 array(56)
t8.flows.ee_1.s.current:       array(56)
t8.flows.ee_1.s.voltage:       array(56)
t8.flows.sig_1.s.power:        array(56)
t8.flows.wat_1.s.flowrate:     array(56)
t8.flows.wat_1.s.pressure:     array(56)
t8.flows.wat_1.s.area:         array(56)
t8.flows.wat_1.s.level:        array(56)
t8.flows.wat_2.s.flowrate:     array(56)
t8.flows.wat_2.s.pressure:     array(56)
t8.flows.wat_2.s.area:         array(56)
t8.flows.wat_2.s.level:        array(56)
t8.fxns.import_ee.s.effstate:  array(56)
t8.fxns.import_ee.m.faults.no_v: array(56)
t8.fxns.import_ee.m.faults.inf_v: array(56)
t8.fxns.import_ee.r.s.effstate: array(56)
t8.fxns.import_ee.r.s.grid_noise: array(56)
t8.fxns.import_ee.r.probdens:  array(56)
t8.fxns.import_water.m.faults.no_wat: array(56)
t8.fxns.import_water.m.faults.less_wat: array(56)
t8.fxns.import_signal.m.faults.no_sig: array(56)
t8.fxns.import_signal.r.s.sig_noise: array(56)
t8.fxns.import_signal.r.probdens: array(56)
t8.fxns.move_water.i.over_pressure: array(56)
t8.fxns.move_water.s.total_flow: array(56)
t8.fxns.move_water.s.eff:      array(56)
t8.fxns.move_water.m.faults.mech_break: array(56)
t8.fxns.move_water.m.faults.short: array(56)
t8.fxns.move_water.r.s.eff:    array(56)
t8.fxns.move_water.r.probdens: array(56)
t8.fxns.move_water.t           array(56)
t8.fxns.move_water.t           array(56)
t8.fxns.export_water.m.faults.block: array(56)
t8.time:                       array(56)
t3.i.finished:                 array(56)
t3.i.on:                       array(56)
t3.r.probdens:                 array(56)
t3.flows.ee_1.s.current:       array(56)
t3.flows.ee_1.s.voltage:       array(56)
t3.flows.sig_1.s.power:        array(56)
t3.flows.wat_1.s.flowrate:     array(56)
t3.flows.wat_1.s.pressure:     array(56)
t3.flows.wat_1.s.area:         array(56)
t3.flows.wat_1.s.level:        array(56)
t3.flows.wat_2.s.flowrate:     array(56)
t3.flows.wat_2.s.pressure:     array(56)
t3.flows.wat_2.s.area:         array(56)
t3.flows.wat_2.s.level:        array(56)
t3.fxns.import_ee.s.effstate:  array(56)
t3.fxns.import_ee.m.faults.no_v: array(56)
t3.fxns.import_ee.m.faults.inf_v: array(56)
t3.fxns.import_ee.r.s.effstate: array(56)
t3.fxns.import_ee.r.s.grid_noise: array(56)
t3.fxns.import_ee.r.probdens:  array(56)
t3.fxns.import_water.m.faults.no_wat: array(56)
t3.fxns.import_water.m.faults.less_wat: array(56)
t3.fxns.import_signal.m.faults.no_sig: array(56)
t3.fxns.import_signal.r.s.sig_noise: array(56)
t3.fxns.import_signal.r.probdens: array(56)
t3.fxns.move_water.i.over_pressure: array(56)
t3.fxns.move_water.s.total_flow: array(56)
t3.fxns.move_water.s.eff:      array(56)
t3.fxns.move_water.m.faults.mech_break: array(56)
t3.fxns.move_water.m.faults.short: array(56)
t3.fxns.move_water.r.s.eff:    array(56)
t3.fxns.move_water.r.probdens: array(56)
t3.fxns.move_water.t           array(56)
t3.fxns.move_water.t           array(56)
t3.fxns.export_water.m.faults.block: array(56)
t3.time:                       array(56)
t1.i.finished:                 array(56)
t1.i.on:                       array(56)
t1.r.probdens:                 array(56)
t1.flows.ee_1.s.current:       array(56)
t1.flows.ee_1.s.voltage:       array(56)
t1.flows.sig_1.s.power:        array(56)
t1.flows.wat_1.s.flowrate:     array(56)
t1.flows.wat_1.s.pressure:     array(56)
t1.flows.wat_1.s.area:         array(56)
t1.flows.wat_1.s.level:        array(56)
t1.flows.wat_2.s.flowrate:     array(56)
t1.flows.wat_2.s.pressure:     array(56)
t1.flows.wat_2.s.area:         array(56)
t1.flows.wat_2.s.level:        array(56)
t1.fxns.import_ee.s.effstate:  array(56)
t1.fxns.import_ee.m.faults.no_v: array(56)
t1.fxns.import_ee.m.faults.inf_v: array(56)
t1.fxns.import_ee.r.s.effstate: array(56)
t1.fxns.import_ee.r.s.grid_noise: array(56)
t1.fxns.import_ee.r.probdens:  array(56)
t1.fxns.import_water.m.faults.no_wat: array(56)
t1.fxns.import_water.m.faults.less_wat: array(56)
t1.fxns.import_signal.m.faults.no_sig: array(56)
t1.fxns.import_signal.r.s.sig_noise: array(56)
t1.fxns.import_signal.r.probdens: array(56)
t1.fxns.move_water.i.over_pressure: array(56)
t1.fxns.move_water.s.total_flow: array(56)
t1.fxns.move_water.s.eff:      array(56)
t1.fxns.move_water.m.faults.mech_break: array(56)
t1.fxns.move_water.m.faults.short: array(56)
t1.fxns.move_water.r.s.eff:    array(56)
t1.fxns.move_water.r.probdens: array(56)
t1.fxns.move_water.t           array(56)
t1.fxns.move_water.t           array(56)
t1.fxns.export_water.m.faults.block: array(56)
t1.time:                       array(56)
[30]:
fig, axs = mdlhists2.plot_line("fxns.move_water.s.eff", "fxns.move_water.s.total_flow",
                    "flows.wat_2.s.flowrate", "flows.wat_2.s.pressure")
../../_images/examples_pump_AST_Sampling_41_0.png
[30]:
(Figure(PyObject <Figure size 600x400 with 4 Axes>), PyObject[PyObject <Axes: title={'center': 'fxns.move_water.s.eff'}, xlabel=' '>, PyObject <Axes: title={'center': 'fxns.move_water.s.total_flow'}, xlabel=' '>, PyObject <Axes: title={'center': 'flows.wat_2.s.flowrate'}, xlabel='time'>, PyObject <Axes: title={'center': 'flows.wat_2.s.pressure'}, xlabel='time'>])

As we can see, MCTS finds more breakage faults (8 instead of 3), as a result of being a more informed search method.

Grey Box Methods

As opposed to black box methods, which share no information about the system state with the agent, grey box methods let the agent sample the random distributions and pass disturbances to the model directly, rather than just passing seeds.

Implementation is based off of: https://github.com/NASA-SW-VnV/AdaStress.jl/blob/master/examples/walk2d/walk2d.ipynb

[31]:
using AdaStress
import AdaStress.GrayBox
using Distributions
using Random

Pump

To use the gray box method, we have to first define which variables in the model to sample/update. fmdtools models have two types of random states: - general random states, which are updated in the behavioral method (whose distributions thus cannot be accessed without looking at the code) - auto-updating random states, which are updated from a given distribution defined with auto_update=(dist,params). These distributions can be accessed directly from the model.

Both can be queried in AdaStress, but using different methods. In general, however, using a Gray Box method means that all stochastic behavior (desired by the analysis) should be represented in AdaStress/Julia, since integration relies on running the model as deterministic.

Below are the random states of the model:

[32]:
rand_states = pump_model.get_rand_states()
[32]:
Dict{Any, Any} with 3 entries:
  "move_water"    => Dict{Any, Any}("eff"=>1.0)
  "import_signal" => Dict{Any, Any}("sig_noise"=>1.0)
  "import_ee"     => Dict{Any, Any}("effstate"=>1.0, "grid_noise"=>1.0)

As well as the auto-updating random states:

[33]:
rand_states = pump_model.get_rand_states(auto_update_only=true)
[33]:
Dict{Any, Any} with 1 entry:
  "move_water" => Dict{Any, Any}("eff"=>1.0)

Simulator

The simulator is roughly the same as the simulation for the black box model except it has an environment which samples stochastic variables and then changes parameters in the model. Note that in this case run_stochastic is set to false, since the variables are being sampled in AdaStress itself (rather than the model).

[34]:
Base.@kwdef mutable struct Simulator <: AdaStress.GrayBox
    sim::PyObject = DynamicProblem(pump_model)
    env::AdaStress.Environment = AdaStress.Environment()
end

function initialize(sim::Simulator)
    sim.env[:eff] = Normal(1.0, 0.2) #creating
    sim.sim=DynamicProblem(pump_model, run_stochastic=false)
    return
end

function update!(sim::Simulator, value::AdaStress.EnvironmentValue)
    #sim.mdl.set_values("MoveWater.eff", value[:eff])
    disturbances=Dict("move_water.s.eff"=>value[:eff])
    sim.sim.update(disturbances=disturbances)
    return
end
[34]:
update! (generic function with 2 methods)

The isterminal and isevent functions will be the same as in the black box model.

[35]:
function isterminal!(sim::Simulator)
    has_faults = sim.sim.mdl.fxns["move_water"].m.any_faults() # our external condition
    terminal = sim.sim.check_sim_end(external_condition=has_faults)
    return terminal
end
function isevent!(sim::Simulator)
    faults = sim.sim.mdl.fxns["move_water"].m.any_faults()
    return faults
end
[35]:
isevent! (generic function with 2 methods)

The interface to adastress is set up below. Of note is the observation interface, which observes eff (which is also the action in this simple setup)

[36]:
Interface.reset!(sim::Simulator) = initialize(sim)

Interface.environment(sim::Simulator) = sim.env

Interface.observe(sim::Simulator) = vcat(sim.sim.mdl.flows.wat_2.pressure, sim.sim.t / sim.sim.t_max)

Interface.step!(sim::Simulator, value::AdaStress.EnvironmentValue) = update!(sim, value)

Interface.isterminal(sim::Simulator) = isterminal!(sim)

Interface.isevent(sim::Simulator) = isevent!(sim)

Interface.distance(sim::Simulator) = float(sum([(16-max(min(i,16), 0))^2 for i in sim.sim.log["flows.wat_1.s.pressure"]]))
[37]:
function mdp_env(; kwargs...)
    mdp = Interface.ASTMDP(Simulator(; kwargs...))
    mdp.rewaan.event_bonus = 2000.0
    return mdp
end
[37]:
mdp_env (generic function with 1 method)

Now using the gray box mdp solver:

[38]:
# AdaStress.enable("SoftActorCritic")
# using AdaStress.SoftActorCritic
[39]:
# Random.seed!(0)
# sac = SAC(;
#     obs_dim=2,
#     act_dim=1,
#     gamma=0.95,
#     act_mins=-1*ones(1),    #number of standard deviations
#     act_maxs=10*ones(1),
#     hidden_sizes=[30,30,30],
#     num_q=2,
#     max_buffer_size=1000000,
#     batch_size=128,
#     epochs=100,
#     update_after=0,
#     update_every=1,
#     steps_per_epoch=54,
#     start_steps=100,
#     max_ep_len=54,
#     num_test_episodes=100,
#     displays=[(:fails, mdp -> mdp.sim.sim.mdl.fxns["MoveWater"].has_fault("mech_break") )],
#     use_gpu=false
# )

# SoftActorCritic.ProgressMeter.ijulia_behavior(:clear)
# ac, info = sac(mdp_env)
[40]:
# using PyPlot
[41]:
# plt.plot(info["fails"])
[42]:
# plt.plot(info["score"])
[43]:
# ac
[44]:
# i=0
# mdlhists3 = Dict()
# mdp = mdp_env()
# for i in 1:100
#     a= AdaStress.replay!(mdp, ac)
#     mdlhists3[i] = mdp.sim.sim.hist
#     i+=1
# end
# mdlhists3 = fmd.analyze.history.History(mdlhists3)
# mdlhists3 = mdlhists3.flatten()
[45]:
# a= AdaStress.replay!(mdp, ac)
[46]:
# info
[47]:
# mdlhists3.plot_line("fxns.move_water.s.eff", "fxns.move_water.s.total_flow",
#                     "flows.wat_2.s.flowrate", "flows.wat_2.s.pressure", aggregation="percentile")
[ ]: