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.