fmdtools.define.architecture

The architecture subpackage provides a representation of Architectures, which may be used to represent agglomerations/interactions of blocks in an overall combined simulation.

Different types of architectures are provided in the following modules:

fmdtools.define.architecture.base

Module for action architectures.

Classes

Architecture: Generic Architecture Class.

class fmdtools.define.architecture.base.Architecture(*args, as_copy=False, h={}, **kwargs)

Bases: Simulable

Superclass for architectures.

Architectures are distinguished from Block classes in that they have flexible role dictionaries that are populated using add_xxx methods in an overall user-defined init_architecture method.

This method is called for a copy using the as_copy option, which copies passed flexible roles.

add_flex_role_obj(flex_role, name, objclass=<class 'fmdtools.define.object.base.BaseObject'>, use_copy=False, **kwargs)

Add a flexible role object to the architecture.

Used for add_fxn, add_flow, etc methods in subclasses. If called during copying (self.as_copy=True), the object is copied instead of instantiated.

Parameters:
  • flex_role (str) – Name of the role dictionary to initialize the object in.

  • name (str) – Name of the object

  • objclass (class, optional) – Class to instantiate in the dict. The default is BaseObject.

  • as_copy (bool) – Whether to instantiate obj as a copy. The default is fault.

  • **kwargs (kwargs) – Non-default kwargs to send to the object class.

add_flow(name, fclass=<class 'fmdtools.define.flow.base.Flow'>, **kwargs)

Add a flow with given attributes to the model.

Parameters:
  • name (str) – Unique flow name to give the flow in the model

  • fclass (Class, optional) – Class to instantiate (e.g. CommsFlow, MultiFlow). Default is Flow. Class must take flowname, p, s as input to __init__() May alternatively provide already-instanced object.

  • kwargs (kwargs) – Dicts for non-default values to p, s, etc

add_flows(*names, fclass=<class 'fmdtools.define.flow.base.Flow'>, **kwargs)

Add a set of flows with the same type and initial parameters.

Parameters:
  • flownames (list) – Unique flow names to give the flows in the model

  • fclass (Class, optional) – Class to instantiate (e.g. CommsFlow, MultiFlow). Default is Flow. Class must take flowname, p, s as input to __init__() May alternatively provide already-instanced object.

  • kwargs (kwargs) – Dicts for non-default values to p, s, etc

add_obj_modes(obj)

Add modes from an object to faultmodes.

add_sim(flex_role, name, simclass, *flownames, **kwargs)

Add a Simulable to the given flex_role.

Parameters:
  • flex_role (str) – Name of the flexible role to add to.

  • name (str) – Name to give the Simulable.

  • simclass (Simulable) – Simulable to instantiate.

  • flownames (list) – List of flows to associate with the function.

  • **kwargs (kwargs) – Flows, dicts for non-default values to p, s, etc.

as_copy
build(update_seed=True, **kwargs)

Construct the overall model structure.

Use in subclasses to build the model after init_architecture is called.

Parameters:

update_seed (bool) – Whether to update the seed

check_role(roletype, rolename)

Check that ‘arch_xa’ role is used for the arch.

copy(flows={})

Copy the architecture at the current state.

Parameters:

flows (dict) – Dict of flows to use in the copy.

Returns:

copy – Copy of the curent architecture.

Return type:

Architecture

flexible_roles = ['flows']
flows
flows_of_type(ftype)

Return the set of flows for each flow type.

flowtypes()

Return the set of flow types used in the model.

get_all_possible_track()

Get all possible tracking options.

get_faults()

Get faults from contained roles.

get_flex_role_objs()
get_flows(*flownames, all_if_empty=True)

Return a list of the model flow objects.

get_rand_states(auto_update_only=False)

Get dictionary of random states throughout the model objs.

h
init_architecture(*args, **kwargs)

Use to initialize architecture.

init_flexible_roles(**kwargs)

Initialize flexible roles.

If initializing as a copy, uses a passed copy instead.

Parameters:

**kwargs (kwargs) – Existing roles (if any).

inject_faults(flexible_role, faults)

Inject faults in the ComponentArchitecture/ASG object obj.

Parameters:
  • obj (TYPE) – DESCRIPTION.

  • faults (TYPE) – DESCRIPTION.

reset()

Reset the architecture and its contained objects.

return_mutables()

Return all mutable values in the block.

Used in static propagation steps to check if the block has changed.

Returns:

states – tuple of all states in the block

Return type:

tuple

roletype = 'arch'
update_seed(seed=[])

Update model seed and the seed in all contained roles.

Must have an associated Rand role.

Parameters:

seed (int, optional) – Seed to use. The default is [].

fmdtools.define.architecture.base.check_model_pickleability(model, try_pick=False)

Check to see which attributes of a model object will pickle.

Provides more detail about functions/flows.

fmdtools.define.architecture.action

Module for action architectures.

Classes

ActionArchitecture: Architecture of multiple Actions.

The ActionArchitecture class is used to represent a sequenced of action taken by an agent. It is a composition of instantiated Action objects, Flow objects, and conditions as shown below:

Structure of an ActionArchitecture

Example Action Architecture connecting action objects with flow objects and conditions.

In the Human action architecture, a human operator percieves and acts on a hazard and the total number of hazards acted on is recorded in the outcome flow. This can also be represented in FRDL using:

Structure of an ActionArchitecture in FRDL

Propagation network of example Action Architecture.

For more info on this example, see: The Action Sequence Graph Demo Model.

class fmdtools.define.architecture.action.ActionArchitecture(**kwargs)

Bases: Architecture

Construct the Action Sequence Graph with the given parameters.

Parameters:
  • initial_action (str/list) –

    Initial action to set as active. Default is ‘auto’
    • ’auto’ finds the starting node of the graph and uses it

    • ’ActionName’ sets the given action as the first active action

    • providing a list of actions will set them all to active

    (if multi-state rep is used)

  • state_rep ('finite-state'/'multi-state') –

    How the states of the system are represented. Default is ‘finite-state’
    • ’finite-state’ means only one action in the system can be active at once (i.e., a finite state machine)

    • ’multi-state’ means multiple actions can be performed at once

  • max_action_prop ('until_false'/'manual'/int) –

    How actions progress. Default is ‘until_false’
    • ’until_false’ means actions are simulated until all outgoing conditions are false

    • providing an integer places a limit on the number of actions that can be

    performed per timestep

  • proptype ('static'/'dynamic'/'manual') –

    Which propagation step to execute the Action Sequence Graph in. Default is ‘dynamic’

    • ’manual’ means that the propagation is performed manually

    (defined in a behavior method)

  • per_timestep (bool) – Defines whether the action sequence graph is reset to the initial state each time-step (True) or stays in the current action (False). Default is False.

action_graph
active_actions
acts
add_act(name, actclass, *flownames, **fkwargs)

Associate an Action with the architecture. Called after add_flow.

Parameters:
  • name (str) – Internal Name for the Action

  • actclass (Action) – Action class to instantiate

  • *flownames (flow) – Flows (optional) which connect the actions

  • duration – Duration of the action. Default is 0.0

  • **kwargs (any) – kwargs to instantiate the Action with.

add_cond(start_action, end_action, name='auto', condition='pass')

Associate a Condition with the ActionArchitecture.

Conditions specify when to precede from one action to the next.

Parameters:
  • start_action (str) – Action where the condition is checked

  • end_action (str) – Action that the condition leads to.

  • name (str) – Name for the condition. Defaults to numbered conditions if none are provided.

  • condition (method) – Method in the class to use as a condition. Defaults to self.condition_pass if none are provided.

build(**kwargs)

Construct the overall model structure.

Use in subclasses to build the model after init_architecture is called.

Parameters:

update_seed (bool) – Whether to update the seed

cond_pass()
conds
copy(**kwargs)

Copy the architecture at the current state.

Parameters:

flows (dict) – Dict of flows to use in the copy.

Returns:

copy – Copy of the curent architecture.

Return type:

Architecture

default_track = ('acts', 'flows', 'active_actions', 'i')
faultmodes
flexible_roles = ['flows', 'acts', 'conds']
flow_graph
initial_action = 'auto'
inject_faults(faults)

Inject faults in the ComponentArchitecture/ASG object obj.

Parameters:
  • obj (TYPE) – DESCRIPTION.

  • faults (TYPE) – DESCRIPTION.

max_action_prop = 'until_false'
per_timestep = False
proptype = 'dynamic'
reset()

Reset the architecture and its contained objects.

rolename = 'aa'
set_active_actions(actions)

Set given action(s) as active.

set_initial_active_action()
state_rep = 'finite-state'

fmdtools.define.architecture.component

Module for action architectures.

Classes

ComponentArchitecture: Architecture defining agglomeration of Components.

class fmdtools.define.architecture.component.ComponentArchitecture(**kwargs)

Bases: Architecture

Class defining Component Architectures.

add_comp(name, compclass, *flownames, **kwargs)

Associate a Component with the architecture. Called after add_flow.

Parameters:
  • name (str) – Internal Name for the Component

  • compclass (Component) – Component class to instantiate

  • *flownames (flow) – Flows (optional) which connect the components

  • **kwargs (any) – kwargs to instantiate the Component with

comps
faultmodes
flexible_roles = ['flows', 'comps']
inject_faults(faults)

Inject faults in the ComponentArchitecture/ASG object obj.

Parameters:
  • obj (TYPE) – DESCRIPTION.

  • faults (TYPE) – DESCRIPTION.

rolename = 'ca'

fmdtools.define.architecture.function

Description: A module for defining Functional Architectures.

Has Classes and Functions:

The FunctionArchitecture class is used to define the high-level function-flow structure of a system model. It is a composition of instantiated Function and Flow objects, as shown below:

Structure of a Model

Example Function Architecture connecting function objects with flow objects.

In FRDL, this object may be represented as:

Example Function Represented in FRDL

Example Function Architecture propagation structure represented in FRDL.

To define a FunctionArchitecture class, it can be helpful to use the following code template:

Structure of a Model

Code template for FunctionArchitecture classes.

class fmdtools.define.architecture.function.FunctionArchitecture(h={}, **kwargs)

Bases: Architecture

Class representing a functional architecture.

Functional architectures enable the execution of multiple Function objects interacting with each other over time. The FunctionArchitecture uses an object-oriented, undirected graph-based model representation to enable the arbitrary propagation of flow states through the functions of the system. As opposed to a procedural directed graph-based model representation, in which each function has an ``input’’ and ``output’’, the undirected graph approach enables one to propagate behaviors in multiple directions. For example, in a pump system, closing a valve can be modelled to not just reduce flow in the downstream pipe, but also increase pressure in upstream pipes.

flowsdict

dictionary of flows objects in the model indexed by name

fxnsdict

dictionary of functions in the model indexed by name

functionorderOrderedSet

Keeps track of function dynamic execution order

staticfxnsOrderedSet

Keeps track of which functions run in static execution step

dynamicfxnsOrderedset

Keeps track of which functions run in dynamic execution step

staticflowslist

Flows to keep track of in static execution step

graphnetworkx graph

multigraph view of functions and flows

Examples

>>> from fmdtools.define.block.function import ExampleFunction
>>> from fmdtools.define.flow.base import ExampleFlow
>>> from fmdtools.define.container.parameter import ExampleParameter
>>> class ExFxnArch(FunctionArchitecture):
...     container_p = ExampleParameter
...     def init_architecture(self, **kwargs):
...         self.add_flow("exf", ExampleFlow, s={'x': 0.0, 'y': 0.0})
...         self.add_fxn("ex_fxn", ExampleFunction, "exf", p=self.p)
...         self.add_fxn("ex_fxn2", ExampleFunction, "exf", p=self.p)
>>> exfa = ExFxnArch(name="exfa")
>>> exfa
exfa ExFxnArch
FUNCTIONS:
ex_fxn ExampleFunction
- ExampleState(x=1.0, y=1.0)
- ExampleMode(mode=standby, faults=set())
ex_fxn2 ExampleFunction
- ExampleState(x=1.0, y=1.0)
- ExampleMode(mode=standby, faults=set())
FLOWS:
exf ExampleFlow flow: ExampleState(x=0.0, y=0.0)

This type of functional architecture only has dynamic functions:

>>> exfa.dynamicfxns
OrderedSet(['ex_fxn', 'ex_fxn2'])
>>> exfa.staticfxns
OrderedSet()

This can in turn be simulated using FunctionArchitecture’s built-in .propagate method. Note how the flow exf accumulates both ex_fxn and ex_fxn2 as reflected in their behavior methods:

>>> exfa.propagate(1.0)
>>> exfa
exfa ExFxnArch
FUNCTIONS:
ex_fxn ExampleFunction
- ExampleState(x=2.0, y=1.0)
- ExampleMode(mode=standby, faults=set())
ex_fxn2 ExampleFunction
- ExampleState(x=2.0, y=1.0)
- ExampleMode(mode=standby, faults=set())
FLOWS:
exf ExampleFlow flow: ExampleState(x=4.0, y=0.0)
>>> exfa.propagate(2.0)
>>> exfa
exfa ExFxnArch
FUNCTIONS:
ex_fxn ExampleFunction
- ExampleState(x=3.0, y=1.0)
- ExampleMode(mode=standby, faults=set())
ex_fxn2 ExampleFunction
- ExampleState(x=3.0, y=1.0)
- ExampleMode(mode=standby, faults=set())
FLOWS:
exf ExampleFlow flow: ExampleState(x=10.0, y=0.0)
add_fxn(name, fclass, *flownames, **fkwargs)

Instantiate a given function in the model.

Parameters:
  • name (str) – Name to give the function.

  • fclass (Class) – Class to instantiate the function as. If no class has been developed, the user can send the block.GenericFxn class.

  • flownames (list) – List of flows to associate with the function.

  • args_f (dict.) – Other parameters to send to the __init__ method of the function class

  • fkwargs (dict) – Parameters to send to __init__ method of the Function superclass

build(require_connections=True, **kwargs)

Build the model graph after the functions have been added.

calc_repaircost(additional_cost=0, default_cost=0, max_cost=inf)

Calculate the repair cost of the fault modes in the model.

Uses given mode cost information for each function mode (in fxn.m).

Parameters:
  • additional_cost (int/float) – Additional cost to add if there are faults in the model. Default is 0.

  • default_cost (int/float) – Cost to use for each fault mode if no fault cost information given in assoc_faultmodes/ Default is 0.

  • max_cost (int/float) – Maximum cost of repair (e.g. cost of replacement). Default is np.inf

Returns:

repair_cost – Cost of repairing the fault modes in the given model

Return type:

float

construct_graph(require_connections=True)

Create .graph nx.graph representation of the model.

default_name = 'model'
default_track = ('fxns', 'flows', 'i')
dynamicfxns
flexible_roles = ['flows', 'fxns']
flowtypes_for_fxnclasses()

Return the flows required by each function class in the model (as a dict).

functionorder
fxnclasses()

Return the set of class names used in the model.

fxns
fxns_of_class(ftype)

Return dict of funcitons corresponding to the given class name ftype.

get_memory()

Return the approximate memory usage of the model.

Includes profile of fxn/flow memory usage.

get_typename()
graph
inject_faults(faults)

Inject faults in the ComponentArchitecture/ASG object obj.

Parameters:
  • obj (TYPE) – DESCRIPTION.

  • faults (TYPE) – DESCRIPTION.

plot_dynamic_run_order(rotateticks=False, title='Dynamic Run Order')

Plot the run order for the model during the dynamic propagation step.

The x-direction is the order of each function executed and the y are the corresponding flows acted on by the given methods.

Parameters:
  • rotateticks (Bool, optional) – Whether to rotate the x-ticks (for bigger plots). The default is False.

  • title (str, optional) – String to use for the title (if any). The default is “Dynamic Run Order”.

Returns:

  • fig (figure) – Matplotlib figure object

  • ax (axis) – Corresponding matplotlib axis

prop_static(time, run_stochastic=False)

Propagate behaviors through model graph (static propagation step).

Parameters:
  • time (float) – Current time-step

  • run_stochastic (bool) – Whether to run stochastic behaviors or use default values. Default is False. Can set as ‘track_pdf’ to calculate/track the probability densities of random states over time.

propagate(time, fxnfaults={}, disturbances={}, run_stochastic=False)

Inject and propagates faults through the graph at one time-step.

Parameters:
  • time (float) – The current time-step.

  • fxnfaults (dict) – Faults to inject during this propagation step. With structure {‘function’:[‘fault1’, ‘fault2’…]}

  • disturbances (dict) – Variables to change during this propagation step. With structure {‘function.var1’:value}

  • run_stochastic (bool) – Whether to run stochastic behaviors or use default values. Default is False. Can set as ‘track_pdf’ to calculate/track the probability densities of random states over time.

reset()

Reset the model to the initial state (with no faults, etc).

return_faultmodes()

Return faultmodes present in the model.

Returns:

  • modes (dict) – Fault modes present in the model indexed by function name

  • modeprops (dict) – Fault mode properties (defined in the function definition). Has structure {fxn:mode:properties}.

return_probdens()

Return the probability density of the model distributions.

rolename = 'fa'
set_functionorder(functionorder)

Manually set the order of functions to be executed.

(otherwise it will be executed based on the sequence of add_fxn calls)

set_vars(*args, **kwargs)

Set variables in the model to set values (useful for optimization, etc.).

Parameters:
  • varlist (list of lists/tuples) –

    List of variables to set, with possible structures:

    [[‘fxnname’, ‘att1’], [‘fxnname2’, ‘comp1’, ‘att2’], [‘flowname’, ‘att3’]] [‘fxnname.att1’, ‘fxnname.comp1.att2’, ‘flowname.att3’]

  • varvalues (list) – List of values corresponding to varlist

  • kwargs (kwargs) – attribute-value pairs. If provided, must be passed using ** syntax: mdl.set_vars(**{‘fxnname.varname’:value})

staticflows
staticfxns

fmdtools.define.architecture.geom

Module for defining Geometry Architectures, agglomerations of individual geometries.

Classes

GeomArchitecture: Architecture of multiple geometries. ExGeomArch: Example GeomArchitecture.

class fmdtools.define.architecture.geom.ExGeomArch(*args, as_copy=False, h={}, **kwargs)

Bases: GeomArchitecture

Example Geometric Architecture for testing etc.

as_copy
flows
h
init_architecture(**kwargs)

Initialize example geoms.

class fmdtools.define.architecture.geom.GeomArchitecture(*args, as_copy=False, h={}, **kwargs)

Bases: Architecture

Agglomeration of multiple geoms/shapes.

Architecture is defined using add_shape method in user-defined init_shapes method.

Examples

for an architecture with the geoms already defined:

>>> class ExGeomArch(GeomArchitecture):
...    def init_architecture(self):
...        self.add_point("ex_point", ExPoint)
...        self.add_line("ex_line", ExLine)
...        self.add_poly("ex_poly", ExPoly)

This can then be used in containing classes (e.g., environments) that need multiple geoms. We can then access the individual geoms in the geoms dict, e.g.,:

>>> ega = ExGeomArch()
>>> ega.geoms()['ex_point'].s
ExGeomState(occupied=False)
>>> ega.h
points.ex_point.s.occupied:   array(101)
lines.ex_line.s.occupied:     array(101)
polys.ex_poly.s.occupied:     array(101)
>>> ega.return_mutables()
((-0.1, 0, 0.0, 1), False, False, False)
add_line(name, lclass=<class 'fmdtools.define.object.geom.GeomLine'>, **kwargs)

Add/instantiate an individual line to the overall architecture.

Parameters:
  • name (str) – Name of the geom object to instantiate.

  • gclass (Geom) – Class defining the geom.

  • **kwargs (kwargs) – kwargs defining the object for gclass.

add_point(name, pclass=<class 'fmdtools.define.object.geom.GeomPoint'>, **kwargs)

Add/instantiate an individual point to the overall architecture.

Parameters:
  • name (str) – Name of the geom object to instantiate.

  • gclass (Geom) – Class defining the geom.

  • **kwargs (kwargs) – kwargs defining the object for gclass.

add_poly(name, pclass=<class 'fmdtools.define.object.geom.GeomPoly'>, **kwargs)

Add/instantiate an individual polygon to the overall architecture.

Parameters:
  • name (str) – Name of the geom object to instantiate.

  • gclass (Geom) – Class defining the geom.

  • **kwargs (kwargs) – kwargs defining the object for gclass.

all_at(*pt)

Find all geoms (and buffers) a given is at.

Parameters:

*pt (x,y) – x, y, z location to check.

Returns:

all_at – Names of geoms where the point is at (and their properties)

Return type:

dict

Examples

>>> exga = ExGeomArch()
>>> exga.all_at(1.0, 1.0)
{'ex_point': ['shape', 'on'], 'ex_line': ['shape', 'on'], 'ex_poly': ['shape']}
>>> exga.all_at(0.0, 0.0)
{'ex_line': ['shape', 'on'], 'ex_poly': ['shape']}
>>> exga.all_at(0.4, 0.3)
{'ex_point': ['on'], 'ex_line': ['on']}
all_possible = ['points', 'lines', 'polys']
as_copy
check_geom_class(gclass, baseclass)

Check that geom class/object inherits from given base class.

container_p

alias of Parameter

default_track = ['points', 'lines', 'polys']
flexible_roles = ['points', 'lines', 'polys']
flows
geoms()

Return a dict of all points, lines, and polygons.

h
init_architecture(**kwargs)

Use this placeholder method to define custom architectures.

return_states()

Return a dict of states for each geom.

rolename = 'ga'
show(geoms={'all': {}}, fig=None, ax=None, figsize=(4, 4), z=False, **kwargs)

Show the shapes of a GeomArchitecture all on one plot.

Parameters:
  • geoms (dict, optional) – Individual shapes to plot and their corresponding kwargs. The default is {‘all’: {}}.

  • fig (matplotlib.figure, optional) – Existing Figure. The default is None.

  • ax (matplotlib.axis, optional) – Existing axis. The default is None.

  • figsize (tuple, optional) – Size for figure (if instantiating). The default is (4, 4).

  • z (bool/number, optional) – If plotting on a 3d axis, set z to a number which will be the z-level. The default is False.

  • **kwargs (kwargs) – Overall kwargs to show.geom for all geoms.

Returns:

  • fig (figure) – Matplotlib figure object

  • ax (axis) – Corresponding matplotlib axis