forked from Jon-b-m/middleware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RoboSurf.js
232 lines (187 loc) · 12.1 KB
/
RoboSurf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
function middleware(iob, currenttemp, glucose, profile, autosens, meal, reservoir, clock, pumphistory, preferences, basal_profile, oref2_variables) {
function round(value, digits) {
if (! digits) { digits = 0; }
var scale = Math.pow(10, digits);
return Math.round(value * scale) / scale;
}
// DYNAMIC ISF: SIGMOID WITH ENHANCED TDD RESPONSE
//Turn on or off
var enable_sigmoidTDD = true;
// Initialize log variables
var log_dyn_enabled = "";
var log_sigmoid_enabled = "";
var log_enableDynCR = "";
var log_myGlucose = "";
var log_target = "";
var log_adjustmentFactor = "";
var log_Average = "";
var log_average_total_data = "";
var log_tdd_dev = "";
var log_TDD_sigmoid_adjustment_factor = "";
var log_TDD_sigmoid_max = "";
var log_TDD_sigmoid_min = "";
var log_TDD_sigmoid_interval = "";
var log_TDD_sigmoid_max_minus_one = "";
var log_TDD_sigmoid_fix_offset = "";
var log_TDD_sigmoid_exponent = "";
var log_tdd_factor = "";
var log_tdd_factor_strength_slider = "";
var log_modified_tdd_factor = "";
var log_minimumRatio = "";
var log_maximumRatio = "";
var log_ratioInterval = "";
var log_max_minus_one = "";
var log_deviation = "";
var log_fix_offset = "";
var log_exponent = "";
var log_sigmoidFactor = "";
var log_minmax_sigmoidFactor = "";
var log_normal_cr = "";
var log_new_isf = "";
var log_protectionmechanism = "Protection Mechanism is Off";
// The Middleware Sigmoid Function will only run if both Dynamic ISF and Sigmoid ISF are OFF and the above variable enable_sigmoidTDD is true
// Initialize Dynamic Status Variables
const dyn_enabled = profile.useNewFormula;
const sigmoid_enabled = profile.sigmoid;
const enableDynCR = profile.enableDynamicCR;
log_dyn_enabled = "Log: dyn_enabled: " + dyn_enabled;
log_sigmoid_enabled = ", Log: sigmoid_enabled: " + sigmoid_enabled;
log_enableDynCR = ", Log: enableDynCR: " + enableDynCR;
// Initialize function variables
const myGlucose = glucose[0].glucose;
const minimumRatio = profile.autosens_min;
const maximumRatio = profile.autosens_max;
var exerciseSetting = false;
const target = profile.min_bg;
const adjustmentFactor = profile.adjustmentFactor;
const past2hoursAverage = oref2_variables.past2hoursAverage;
const average_total_data = oref2_variables.average_total_data;
var weightedAverage = oref2_variables.weightedAverage;
const duration = oref2_variables.duration;
const date = oref2_variables.date;
const isf = profile.sens;
// Log function variables
log_myGlucose = "myGlucose: " + myGlucose + ", ";
log_minimumRatio = ", Log: minimumRatio: " + minimumRatio;
log_maximumRatio = ", Log: maximumRatio: " + maximumRatio;
log_target = "Target: " + target;
log_adjustmentFactor = "AdjustmentFactor: " + adjustmentFactor;
log_past2hoursAverage = "24hr TDD: " + round(past2hoursAverage, 2);
log_average_total_data = "2-week TDD: " + round(average_total_data, 2);
log_weightedAverage = "TDD Weighted Average: " + round(weightedAverage, 2);
var log_duration = ", Log: duration: " + duration;
var log_date = ", Log: date: " + date;
var log_isf = "Profile ISF: " + isf;
// Establish Guards
if (minimumRatio == maximumRatio) {
enable_sigmoidTDD = false;
}
if (profile.high_temptarget_raises_sensitivity || profile.exercise_mode || oref2_variables.isEnabled) {
exerciseSetting = true;
}
if (target >= 118 && exerciseSetting) {
enable_sigmoidTDD = false;
}
// Sensitivity Protection Mechanism: If 24hr TDD is less than 2-Week TDD (more sensitive), set weighted average TDD to the 24hr TDD value)
if (past2hoursAverage < average_total_data) {
weightedAverage = past2hoursAverage;
var log_protectionmechanism = " Protection Mechanism On: Weighted Average adjusted to 24hr TDD";
}
// Sigmoid Function
//Only use when dynISF setting is off and Sigmoid is off and the constant enable_sigmoidTDD = true.
if (enable_sigmoidTDD && !dyn_enabled && !sigmoid_enabled) {
// DYNISF SIGMOID MODIFICATION #1
// Account for delta in TDD of insulin. Define a TDD Factor using a Sigmoid curve that approximates the TDD delta effect used in the Chris Wilson DynISF approach.
// This TDD delta effect is not linear across BGs and requires a curve to mimic.
// ORIGINAL SIGMOID APPROACH: const tdd_factor = tdd_averages.weightedAverage / tdd_averages.average_total_data;
// Define TDD deviation variable for use in TDD Sigmoid curve based on current percent change between Daily TDD deviation and 2 Week Deviation
// This approach will normalize this variable for any TDD value to ensure a standard TDD Factor sigmoid curve for all users
const tdd_dev = (weightedAverage / average_total_data - 1) * 10;
log_tdd_dev = "Log: tdd_dev: " + tdd_dev;
// Hard-code TDD Factor Sigmoid inputs
// These inputs have been modeled to create a TDD Factor that, when used in the Sigmoid DynISF function, closely approximates the TDD delta effect for ULTRA-RAPID used in the Chris Wilson (Logarithmic) DynISF approach.
// These inputs are not expected to require user change for ultra-rapid insulin; instead the strength of this factor can be modified below using the tdd_factor_strength_slider.
// To model the effects of any changes to these values, or adjust for RAPID insulin, see: https://docs.google.com/spreadsheets/d/1k4sGaZYf2t-FbfY8rViqvUnARx_Gu5K_869AH2wgg_A/edit?usp=sharing
const TDD_sigmoid_adjustment_factor = .41;
const TDD_sigmoid_max = 3.25;
const TDD_sigmoid_min = .7;
log_TDD_sigmoid_adjustment_factor = ", Log: TDD_sigmoid_adjustment_factor: " + TDD_sigmoid_adjustment_factor;
log_TDD_sigmoid_max = ", Log: TDD_sigmoid_max: " + TDD_sigmoid_max;
log_TDD_sigmoid_min = ", Log: TDD_sigmoid_min: " + TDD_sigmoid_min;
// Define a TDD Factor Sigmoid curve using same method as the DynISF Sigmoid approach below
const TDD_sigmoid_interval = TDD_sigmoid_max - TDD_sigmoid_min;
const TDD_sigmoid_max_minus_one = TDD_sigmoid_max - 1;
const TDD_sigmoid_fix_offset = (Math.log10(1/TDD_sigmoid_max_minus_one - TDD_sigmoid_min / TDD_sigmoid_max_minus_one) / Math.log10(Math.E));
const TDD_sigmoid_exponent = tdd_dev * TDD_sigmoid_adjustment_factor + TDD_sigmoid_fix_offset;
log_TDD_sigmoid_interval = ", Log: TDD_sigmoid_interval: " + TDD_sigmoid_interval;
log_TDD_sigmoid_max_minus_one = ", Log: TDD_sigmoid_max_minus_one: " + TDD_sigmoid_max_minus_one;
log_TDD_sigmoid_fix_offset = ", Log: TDD_sigmoid_fix_offset: " + TDD_sigmoid_fix_offset;
log_TDD_sigmoid_exponent = ", Log: TDD_sigmoid_exponent: " + TDD_sigmoid_exponent;
// The TDD Factor sigmoid function
const tdd_factor = TDD_sigmoid_interval / (1 + Math.exp(-TDD_sigmoid_exponent)) + TDD_sigmoid_min;
log_tdd_factor = ", Log: tdd_factor: " + round(tdd_factor, 2);
// Adjust the stregnth of the TDD Factor; 100% = FULL TDD delta effect similar to Chris Wilson (Logarithmic) DynISF, 50% = half the effect, etc.
const tdd_factor_strength_slider = 1;
log_tdd_factor_strength_slider = ", Log: log_tdd_factor_strength_slider: " + tdd_factor_strength_slider;
// The user adjusted TDD factor based on above % slider
const modified_tdd_factor = ((tdd_factor - 1) * tdd_factor_strength_slider) + 1;
log_modified_tdd_factor = "Modified_tdd_factor: " + round(modified_tdd_factor, 2);
// The Dynamic ISF Sigmoid Code
const ratioInterval = maximumRatio - minimumRatio;
var max_minus_one = maximumRatio - 1;
log_minimumRatio = ", Log: minimumRatio: " + minimumRatio;
log_maximumRatio = ", Log: maximumRatio: " + maximumRatio;
log_ratioInterval = ", Log: ratioInterval: " + ratioInterval;
log_max_minus_one = ", Log: max_minus_one: " + max_minus_one;
// DYNISF SIGMOID MODIFICATION #2
// The TDD delta effect in Chris Wilson (Logarithmic) DynISF approach allows ISF to shift when BG is below target BG (unlike the original Sigmoid DynamicISF approach).
// The following math applies the new TTD factor to the target BG to this shift.
// Like the original Sigmoid approach, Profile ISF will be applied at target but only when Daily TDD = 2 Week TDD.
// ORIGINAL SIGMOID APPROACH: Blood glucose deviation from set target (the lower BG target) converted to mmol/l to fit current formula.
// ORIGINAL SIGMOID APPROACH: const bg_dev = (current_bg - profile.min_bg) * 0.0555;
const deviation = (myGlucose - (target / modified_tdd_factor)) * 0.0555;
log_deviation = ", Log: deviation: " + deviation;
//Makes sigmoid factor(y) = 1 when BG deviation(x) = 0.
const fix_offset = (Math.log10(1/max_minus_one-minimumRatio/max_minus_one) / Math.log10(Math.E));
log_fix_offset = ", Log: fix_offset: " + fix_offset;
//Exponent used in sigmoid formula
const exponent = deviation * adjustmentFactor * modified_tdd_factor + fix_offset;
log_exponent = ", Log: exponent: " + exponent;
// The sigmoid function
var sigmoidFactor = ratioInterval / (1 + Math.exp(-exponent)) + minimumRatio;
log_sigmoidFactor = ", Log: sigmoidFactor: " + sigmoidFactor;
//Respect min/max ratios
sigmoidFactor = Math.max(Math.min(maximumRatio, sigmoidFactor), sigmoidFactor, minimumRatio);
log_minmax_sigmoidFactor = ", Log: sigmoidFactor post min/max: " + sigmoidFactor;
// Sets the new ratio
autosens.ratio = sigmoidFactor;
const normal_cr = profile.carb_ratio;
log_normal_cr = "Log: normal_cr: " + normal_cr;
// Dynamic CR. Use only when the setting 'Enable Dyanmic CR' is on in FAX Dynamic Settings
if (autosens.ratio > 1 && enableDynCR) {
profile.carb_ratio /= ((autosens.ratio - 1) / 2 + 1);
} else if (enableDynCR) { profile.carb_ratio /= autosens.ratio; }
const new_isf = round(profile.sens/autosens.ratio,0);
log_new_isf = "New ISF: " + new_isf;
// Return All Function Data to Test Middleware Function Operation
//return "Using Middleware function, the autosens ratio has been adjusted with sigmoid factor using the following data: " + log_past2hoursAverage + log_average_total_data + log_weightedAverage + log_tdd_dev + log_TDD_sigmoid_adjustment_factor + log_TDD_sigmoid_max + log_TDD_sigmoid_min + log_TDD_sigmoid_interval + log_TDD_sigmoid_max_minus_one + log_TDD_sigmoid_fix_offset + log_TDD_sigmoid_exponent + log_tdd_factor + log_tdd_factor_strength_slider + log_modified_tdd_factor + log_myGlucose + log_target + log_isf + log_adjustmentFactor + log_minimumRatio + log_maximumRatio + log_ratioInterval + log_max_minus_one + log_deviation + log_fix_offset + log_exponent + log_sigmoidFactor + log_minmax_sigmoidFactor + log_new_isf;
// DYNAMIC SMB DELIVERY RATIO
// Initialize function variables
var smb_delivery_ratio = profile.smb_delivery_ratio;
// User-Defined function settings
const smb_delivery_ratio_min = profile.smb_delivery_ratio;
const smb_delivery_ratio_max = 1;
const smb_delivery_ratio_bg_range = 65;
// The Scaling Function
// If BG between target and top of BG Range, scale SMB Delivery ratio
if (myGlucose >= target && myGlucose <= (target+smb_delivery_ratio_bg_range)) {
smb_delivery_ratio = (myGlucose - target) * ((smb_delivery_ratio_max - smb_delivery_ratio_min) / smb_delivery_ratio_bg_range) + smb_delivery_ratio_min;
}
// If BG above user-defined BG range, use SMB ratio max
if (myGlucose > (target + smb_delivery_ratio_bg_range)) {
smb_delivery_ratio = smb_delivery_ratio_max;
}
profile.smb_delivery_ratio = round(smb_delivery_ratio,2);
return "Using RoboSurf the autosens ratio has been set to: " + round(autosens.ratio, 2) + ". " + log_protectionmechanism + " New ISF = " + round(new_isf, 2) + ". CR adjusted from " + round(normal_cr,2) + " to " + round(profile.carb_ratio,2) + " 24hr TDD: " + round(past2hoursAverage, 2) + " 2-week TDD: " + round(average_total_data, 2) + " TDD Weighted Average: " + round(weightedAverage, 2) + ". SMB Delivery Ratio set to: " + profile.smb_delivery_ratio;
}
}