Miscellanous filters
SmartCGMS is distributed with a larger set of filters, that fulfills miscellanous roles during signal processing. Following sections roughly describe their function, configuration and important notes.
Native scripting
Using the native scripting filter, you can quickly develop a new native filter without the need for compiling the SmartCGMS SDK explicitly. The only requirement is to have a development environment set up and ready for use. For example, you can use MS Visual Studio on MS Windows, gcc or clang on GNU/Linux or macOS.
You need to specify the environment paths into the native filter configuration - the path to the compiler, to the environment setup script, SmartCGMS SDK and the actual file to be compiled. Once you compile your native script, you can distribute it as-is, as it does not rely on the buildsystem anymore. If the native script is changed, the native scripting filter will detect this based on the change timestamp and will rebuild your native script to keep it up-to-date.
The native filter wrapper will forward signals to your code based on the configuration. For example, you may request the IG, CHO and insulin signals, and the wrapper will supply them to your code through the signals array at their respective index.
Every native filter must have an entry point called execute
with the following parameters:
void execute(GUID& signal_id, double& device_time, double& level, HRESULT& rc, TNative_Environment& environment, const void* context) {
...
}
Here, the signal_id
denotes the signal GUID that triggered the execution, device_time
marks the current time of the event, level
contains the measured/calculated level, rc
is a reference to return code you should set before returning (S_OK
for success, and so on), environment
refers to the environment wrapper you can use to perform SmartCGMS-related actions and
context
is a transparent pointer to native execution context you need to use for some actions regarding the environment.
The array environment.signal_id
refers to the signal GUIDs configured in the filter.
The following example shows, how to create a signal mapping filter, that remaps all configured signals to the first one:
#include <iface/NativeIface.h>
void execute(GUID& sig_id, double& device_time, double& level, HRESULT& rc, TNative_Environment& environment, const void* context) {
const size_t sig_idx = environment.current_signal_index;
if (sig_idx != 0 && sig_idx < native::max_signal_count) { // map all incoming signals to signal on index 0
sig_id = environment.signal_id[0];
}
}
You can also specify custom data, that is stored per-segment. If the script defines a structure or class named TCustom_Data
, the wrapper registers the type and allocates an additional memory in each segment
record into environment->custom_data
, typed as the custom type.
Signal decoupling
This filter shares the base functionality with the mapping filter, except that it evaluates a configured condition prior to mapping. Furthermore, the mapping could be switched off and the filter might just collect statistics about the signal.
The Condition
configuration parameter holds a string, that is evaluated on every source signal GUID match. If the condition is true, then the filter might either map the signal ID to the desired ID, collect
statistics about the passing events, or both. The Output_CSV_file
configuration parameter points to an output file to be written after the execution ends.
Signal statistics
The signal statistics filter calculates basic statistics about the signal. Namely, it calculates and stores:
- minimum value
- 25th percentile
- median (50th percentile)
- 75th percentile
- 95th percentile
- 99th percentile
- maximum value
The Output_CSV_file
configuration parameter points to an output file, that stores the signal statistics after the execution ends.
Impulse response filter
This filter performs an on-line moving average smoothing of the signal given as Signal_ID
configuration parameter. The Response_Window
configuration parameter holds a time span (window), for which the
smoothing is performed. Please note, that this filter overwrites the original signal values with smoothed ones.
There is currently no way to add weights to the impulse response, and therefore there is no such filter maintaining a weigthed moving average (WMA). However, if a WMA implementation is desired, please, refer to the examples of the SmartCGMS SDK - there is a native script example, that performs the WMA.
Basal to bolus
This filter emulates the function of an insulin pump, and therefore is specialized to diabetes treatment. In a typical glucose control scenario, there is an insulin pump, that doses insulin in two modes - bolus and basal insulin. The basal insulin is a continuous dosage, in which the patient sets the infusion rate and the pump maintains the dosage by its internal logic. The bolus insulin is a single larger dose of insulin, which is dosed at one time. However, the insulin pump contains shared logic for both basal and bolus insulin, and therefore we need to spread the continuous dosage to discrete infusions.
The logic of this filter converts the basal infusion rate to multiple small bolus doses, which reflects a real scenario.
The filter encapsulates a model, which has two parameters: minimal dosage and spreading period. The minimal dosage parameter represents a minimal dosage resolution of the pump hardware, e.g., the pump is physically unable to dose amounts smaller than 0.05 U. The spreading period is the period between the boluses generated from basal infusion rate setting.