def test_in_range_and_rising_bolus(self): glucose = self.load_glucose_value_fixture( "recommend_temp_basal_in_range_and_rising") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(0.325, dose[0]) # Less existing temp dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0.8, self.MAX_BOLUS, 0.025) self.assertEqual(0, dose[0])
def test_no_input_glucose_bolus(self): glucose = ([], []) dose = recommended_bolus(*glucose, *self.TARGET_RANGE, datetime.now(), self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(0, dose[0])
def test_rise_after_dia_bolus(self): glucose = self.load_glucose_value_fixture( "far_future_high_bg_forecast") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(0, dose[0])
def test_start_low_and_end_just_above_range_bolus(self): glucose = self.load_glucose_value_fixture( "recommended_temp_start_low_end_just_above_range") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(0.275, dose[0])
def test_flat_and_high_bolus(self): glucose = self.load_glucose_value_fixture( "recommend_temp_basal_flat_and_high") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(1.575, dose[0])
def test_dropping_below_range_then_rising_bolus(self): glucose = self.load_glucose_value_fixture( "recommend_temp_basal_dropping_then_rising") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(1.4, dose[0]) self.assertEqual("predictedGlucoseBelowTarget", dose[2][0])
def test_start_below_suspend_threshold_end_high_bolus(self): glucose = self.load_glucose_value_fixture( "recommend_temp_basal_start_low_end_high") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], 70, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(0, dose[0]) self.assertEqual("glucoseBelowSuspendThreshold", dose[2][0]) self.assertEqual(60, dose[2][1])
def test_start_low_end_high_bolus(self): glucose = self.load_glucose_value_fixture( "recommend_temp_basal_start_low_end_high") dose = recommended_bolus(*glucose, *self.TARGET_RANGE, glucose[0][0], self.SUSPEND_THRESHOLD, *self.SENSITIVITY, self.WALSH_MODEL, 0, self.MAX_BOLUS, 0.025) self.assertEqual(1.575, dose[0]) self.assertEqual("predictedGlucoseBelowTarget", dose[2][0]) self.assertEqual(60, dose[2][1])
def update_predicted_glucose_and_recommended_basal_and_bolus( at_date, glucose_dates, glucose_values, momentum_dates, momentum_values, carb_effect_dates, carb_effect_values, insulin_effect_dates, insulin_effect_values, retrospective_effect_dates, retrospective_effect_values, target_starts, target_ends, target_mins, target_maxes, suspend_threshold, sensitivity_starts, sensitivity_ends, sensitivity_values, model, basal_starts, basal_rates, basal_minutes, max_basal_rate, max_bolus, last_temp_basal, duration=30, continuation_interval=11, rate_rounder=None ): """ Generate glucose predictions, then use the predicted glucose along with settings and dose data to recommend a temporary basal rate and a bolus Arguments: at_date -- date to calculate the temp basal and bolus recommendations glucose_dates -- dates of glucose values (datetime) glucose_values -- glucose values (in mg/dL) momentum_dates -- times of calculated momentums (datetime) momentum_values -- values (mg/dL) of momentums carb_effect_dates -- times of carb effects (datetime) carb_effect -- values (mg/dL) of effects from carbs insulin_effect_dates -- times of insulin effects (datetime) insulin_effect -- values (mg/dL) of effects from insulin correction_effect_dates -- times of retrospective effects (datetime) correction_effect -- values (mg/dL) retrospective glucose effects target_starts -- start times for given target ranges (datetime) target_ends -- stop times for given target ranges (datetime) target_mins -- the lower bounds of target ranges (mg/dL) target_maxes -- the upper bounds of target ranges (mg/dL) suspend_threshold -- value at which to suspend all insulin delivery (mg/dL) sensitivity_starts -- list of time objects of start times of given insulin sensitivity values sensitivity_ends -- list of time objects of start times of given insulin sensitivity values sensitivity_values -- list of sensitivities (mg/dL/U) model -- list of insulin model parameters in format [DIA, peak_time] if exponential model, or [DIA] if Walsh model basal_starts -- list of times the basal rates start at basal_rates -- list of basal rates(U/hr) basal_minutes -- list of basal lengths (in mins) max_basal_rate -- max basal rate that Loop can give (U/hr) max_bolus -- max bolus that Loop can give (U) last_temp_basal -- list of last temporary basal information in format [type, start time, end time, basal rate] duration -- length of the temp basal (mins) continuation_interval -- length of time before an ongoing temp basal should be continued with a new command (mins) rate_rounder -- the smallest fraction of a unit supported in basal delivery; if None, no rounding is performed Output: The predicted glucose values, recommended temporary basal, and recommended bolus in the format [ (predicted glucose times, predicted glucose values), temporary basal recommendation, bolus recommendation ] """ assert glucose_dates, "expected to receive glucose data" assert target_starts and sensitivity_starts and basal_starts and model,\ "expected to receive complete settings data" if (not momentum_dates and not carb_effect_dates and not insulin_effect_dates ): warnings.warn("Warning: expected to receive effect data") return (None, None, None) predicted_glucoses = predict_glucose( glucose_dates[-1], glucose_values[-1], momentum_dates, momentum_values, carb_effect_dates, carb_effect_values, insulin_effect_dates, insulin_effect_values, retrospective_effect_dates, retrospective_effect_values ) # Dosing requires prediction entries at least as long as the insulin # model duration. If our prediction is shorter than that, extend it here. if len(model) == 1: # Walsh model final_date = glucose_dates[-1] + timedelta(hours=model[0]) else: final_date = glucose_dates[-1] + timedelta(minutes=model[0]) if predicted_glucoses[0][-1] < final_date: predicted_glucoses[0].append(final_date) predicted_glucoses[1].append(predicted_glucoses[1][-1]) pending_insulin = get_pending_insulin( at_date, basal_starts, basal_rates, basal_minutes, last_temp_basal ) temp_basal = recommended_temp_basal( *predicted_glucoses, target_starts, target_ends, target_mins, target_maxes, at_date, suspend_threshold, sensitivity_starts, sensitivity_ends, sensitivity_values, model, basal_starts, basal_rates, basal_minutes, max_basal_rate, last_temp_basal, duration, continuation_interval, rate_rounder ) bolus = recommended_bolus( *predicted_glucoses, target_starts, target_ends, target_mins, target_maxes, at_date, suspend_threshold, sensitivity_starts, sensitivity_ends, sensitivity_values, model, pending_insulin, max_bolus, rate_rounder ) return { "predicted_glucose_dates": predicted_glucoses[0], "predicted_glucose_values": predicted_glucoses[1], "recommended_temp_basal": temp_basal, "recommended_bolus": bolus }