# Mouse-GYM Training Protocols

A Mouse-GYM Training Protocol is a mechanism for incremental training through one or more phases of device configuration
and system behavior.  Progress within a protocol is tracked individually for each animal.  Animals may have multiple
protocol histories.

## Training Protocols
A Training Protocol is the definition of the specific procedures and requirements to move through phases of training.
It is defined once.  The progress of individual animals with a protocol is tracked separately.  A protocol consists of:
* `id` a unique identifier for each protocol generated by the system (not guaranteed to be user-friendly)
* `name` a user-friendly name/identifier
* `description` more detailed information than the name (optional)
* `phases` a set of Training Phases (defined later) to progress through

## Training Phases
A Training Phase defines the state of the system for given phase of training (which can be modified during the phase)
and requirements for exiting the phase.  One set of requirements represents the condition(s) to advance to the next
phase if there is one.  A second, optional set of requirements represent the condition(s) to fall back to the previous
phase due to insufficient progress in some amount of time or any other supported metric.

At the end of every behavior session, three steps are taken for the current phase:
* Any defined "session actions" are called.  These do not _directly_ affect exiting the phase.
  * An example could be moving the pellet arm after every session where a pellet is consumed.
  * A session action could modify a property of the training progress that _would_ affect the phase exit behavior to follow
  * These actions, if present, are also called at the start of the phase
* If fall-back conditions are defined, they are evaluated and if the result is True, the system transitions to the previous phase
* If advance conditions are defined, they are evaluated and if the result is True, the system transitions to the next phase

Session actions, fall-back conditions, and advance conditions are all optional.

The definition of what is a separate training phase vs. something that is modified during session actions (e.g., changing
pellet delivery location) is up to the Training Protocol writer.

A Training Phase definition consists of:
* `id` a unique identifier for each phase generated by the system (not guaranteed to be user-friendly)
* `name` a user-friendly name/identifier
* `description` more detailed information than the name (optional)
* `fallback condition` condition(s) for returning to the previous phase
* `advance condition` condition(s) for advancing to the next phase
* `session actions` predefined actions or arbitrary Python code to execute after each session

There are also default settings for most behavior algorithm settings, such as:
* `pellet delivery enabled` 
* `pellet covering enabled` 
* `baseline magnet intensity` 
* `reach distance to uncover`
* `auto-clamp enabled`
* `auto-clamp release delay`
* `auto-clamp load count`

These are set when the phase is entered.  They may be changed by session actions.

## Training Predicates
Training Predicates define the conditions for exiting a phase, either to advance or fall back.  There are built-in
predicates for simple tests and a Python predicate that will evaluate user-defined Python code.  Predicates include:
* `Number Comparison` will test <, <=, ==, >=, or > for integer or floating point values
* `String Comparison` will test string values
* `Python` will execute user-defined python code _(not fully implemented)_
* `Compound` can be set to return True if _all_ child predicates are True or set to return True if _any_ child predicates are True (OR vs AND)

Compound predicates can be used to assemble any combination of any or all conditions at any depth.

Predicates have access to all public behavior algorithm, tunnel device, and pellet device public properties, as well as
all properties tracked as progress for the animal such as pellets consumed.  Properties at any depth in these objects
can be reached via property paths delimited by periods such as `progress.pellets_consumed`.

## Training Actions
Training Actions are performed each time a session completes.  They can be used to make adjustments during a phase that
do not constitute moving a new phase.

Similar to predicates, there are predefined actions that do not require user-defined Python code to execute.  If none of
the predefined actions provide the required functionality, user-defined Python code can be used.  These include:
* `HeadMagnetIntensityAction` - defines a range of values (start, increment, end) of head magnet intensity values to progress through based on the specified number of pellets successfully consumed for each step
* `ReachDistanceAction` - defines a range of values (start, increment, end) of pellet-y offset values to progress through based on the specified number of pellets successfully consumed for each step
* `Python` - will execute user-defined python code _(not fully implemented)_


Training actions may also contribute to determining whether a phase is complete.  In addition to checking predicates, if
an action is marked as `has_progress`, its `is_complete` property will be evaluated after each session.

## Training Progress

Training Progress is the per-animal tracking of progress through the protocol and each phase.  This is primarily used
to evaluate exit conditions.  Values include:
* Amount of time since the phase was first entered (calendar time, i.e., Sept. 12, even if the system was not running the entire time)
* Active time in phase - the amount of time actually spend with the phase active and system running
* Pellets presented
* Pellets consumed
* Successful reaches
* Starting pellet delivery location for this phase
* Current pellet delivery location (might be different if modified by actions)

This a partial list and the list will grow as more metrics are required for assessing progress or reporting.

There is also a generic dictionary available for Python session actions and predicates to read and write any JSON
serializable value.

###  Notes for Code Development
* The user-facing Training Protocol entity is represented in the class `TrainingPlan` due to specific use of `Protocol` in Python.
