Contexts

Contexts, in NGC-Sim-Lib, are the top-level containers that hold everything used to define a model / dynamical system. On their own, contexts have no runtime logic; they rely on their internal processes and components to build a complete, working model.

Defining a Context

To define a context (ngcsimlib.Context), NGC-Sim-Lib leverages the with block; this means that to create a new context, simply start with the statement with Context("myContext") as ctx: and a new context will be created. (Important Note: names are unique; if a context is created with the same name, they will be the same context and, thus, there might be conflicts). A defined context does not do anything on its own.

Adding Components

To add components to a context, simply initialize components while inside the with block of the context. Any component defined while inside this block will automatically be added and tacked-on to the context object.

Wiring Components

Inside of a model / dynamical system, components will need to pass data to one another; this is configured within the context. To connect the compartments of two components, follow the pattern: mySource.output >> myDestination.input, where output and input are compartments inside their respective components. This format will ensure that, when processes are being run, the value will flow properly from component to component.

Operators

There is a special type of wire called an operator; this performs a simple operation on the compartment values as the data flows from one component to another. Generally, these are use for simple mathematical operations, such as negation Negate(mySource.output) >> myDestination.input or the summation of multiple compartments into one Summation(mySource1.output, mySource2.output, ...) >> myDestination.input. Note that operators can be chained, so it would be possible to negate one or more of the inputs that flow into the summation.

Adding Processes

To add processes to a context, simply initialize the process and add all of its steps while inside the with-block of the process.

Exiting the with block

When the context exits the with-block, it will re-compile the entire model. Behind the scenes, this is calling recompile on the context itself; it is possible to manually trigger the recompile step, but doing so can break certain connections (between components/compartments), so use this functionality sparingly.

Saving and Loading

The context’s one unique job is the handling of the “saving” (serialization) and “loading” (de-serialization) of models to disk. By default, calling save_to_json(...) will create the correct file structure as well as the core files needed and load the context in the future. To load / de-serialize a model, calling Context.load(...) will load the context in from a directory; something important to note is that loading in a context entails effectively recreating the components with their initial values using their arguments as well as keywords arguments (excluding those that cannot be serialized). This means that, if you have a trained model, ensure that your components have a save method defined that will handle the saving and loading of all values within their compartments.