Esempio n. 1
0
    def test_carb_effect_with_zero_entry(self):
        input_ice = self.load_ice_input_fixture("ice_35_min_input")

        carb_ratio_tuple = self.load_schedules()

        default_absorption_times = self.DEFAULT_ABSORPTION_TIMES

        carb_entry_starts = [input_ice[0][0]]
        carb_entry_quantities = [0]
        carb_entry_absorptions = [120]

        (absorptions,
         timelines,
         entries  # pylint: disable=W0612
         ) = map_(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             *input_ice,
             *carb_ratio_tuple,
             self.INSULIN_SENSITIVITY_START_DATES,
             self.INSULIN_SENSITIVITY_END_DATES,
             self.INSULIN_SENSITIVITY_VALUES,
             default_absorption_times[0] / default_absorption_times[1],
             default_absorption_times[1],
             0
             )

        self.assertEqual(len(absorptions), 1)
        self.assertEqual(absorptions[0][6], 0)
Esempio n. 2
0
    def test_dynamic_glucose_effect_absorption_never_fully_observed(self):
        input_ice = self.load_ice_input_fixture("ice_slow_absorption")

        (carb_starts,
         carb_values,
         carb_absorptions
         ) = self.load_carb_entry_fixture()

        carb_ratio_tuple = self.load_schedules()

        default_absorption_times = self.DEFAULT_ABSORPTION_TIMES

        carb_entry_starts = [carb_starts[1]]
        carb_entry_quantities = [carb_values[1]]
        carb_entry_absorptions = [carb_absorptions[1]]

        (expected_dates,
         expected_values
         ) = self.load_cob_output_fixture(
             "dynamic_glucose_effect_never_fully_observed_output"
             )

        (absorptions,
         timelines,
         entries,  # pylint: disable=W0612
         ) = map_(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             *input_ice,
             *carb_ratio_tuple,
             self.INSULIN_SENSITIVITY_START_DATES,
             self.INSULIN_SENSITIVITY_END_DATES,
             self.INSULIN_SENSITIVITY_VALUES,
             default_absorption_times[1] / default_absorption_times[0],
             default_absorption_times[1],
             0
             )

        self.assertEqual(len(absorptions), 1)
        self.assertIsNotNone(absorptions[0])
        self.assertAlmostEqual(absorptions[0][6], 10488/60, 2)

        (effect_dates,
         effect_values
         ) = dynamic_glucose_effects(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             absorptions,
             timelines,
             *carb_ratio_tuple,
             self.INSULIN_SENSITIVITY_START_DATES,
             self.INSULIN_SENSITIVITY_END_DATES,
             self.INSULIN_SENSITIVITY_VALUES,
             default_absorption_times[1],
             delay=10,
             delta=5,
             start=input_ice[0][0],
             end=(
                 input_ice[0][0]
                 + timedelta(hours=18)
                 )
             )

        assert len(expected_dates) == len(effect_dates)
        for i in range(0, len(expected_dates)):
            self.assertEqual(
                expected_dates[i], effect_dates[i]
            )
            self.assertAlmostEqual(
                expected_values[i], effect_values[i], 2
            )
Esempio n. 3
0
    def test_dynamic_absorption_fully_observed(self):
        input_ice = self.load_ice_input_fixture("ice_1_hour_input")

        (carb_starts,
         carb_values,
         carb_absorptions
         ) = self.load_carb_entry_fixture()

        carb_ratio_tuple = self.load_schedules()

        default_absorption_times = self.DEFAULT_ABSORPTION_TIMES

        carb_entry_starts = [carb_starts[0]]
        carb_entry_quantities = [carb_values[0]]
        carb_entry_absorptions = [carb_absorptions[0]]

        (expected_dates,
         expected_values
         ) = self.load_cob_output_fixture("ice_1_hour_output")

        (absorptions,
         timelines,
         entries,  # pylint: disable=W0612
         ) = map_(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             *input_ice,
             *carb_ratio_tuple,
             self.INSULIN_SENSITIVITY_START_DATES,
             self.INSULIN_SENSITIVITY_END_DATES,
             self.INSULIN_SENSITIVITY_VALUES,
             default_absorption_times[1] / default_absorption_times[0],
             default_absorption_times[1],
             0
             )

        self.assertEqual(len(absorptions), 1)
        self.assertIsNotNone(absorptions[0])

        # No remaining absorption
        self.assertEqual(absorptions[0][6], 0)

        # All should be absorbed
        self.assertEqual(absorptions[0][0], 44)

        (cob_dates,
         cob_values
         ) = dynamic_carbs_on_board(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             absorptions,
             timelines,
             default_absorption_times[1],
             delay=10,
             delta=5,
             start=input_ice[0][0],
             end=(
                 input_ice[0][0]
                 + timedelta(hours=6)
                 )
             )

        assert len(expected_dates) == len(cob_dates)
        for i in range(0, len(expected_dates)):
            self.assertEqual(
                expected_dates[i], cob_dates[i]
            )
            self.assertAlmostEqual(
                expected_values[i], cob_values[i], 1
            )
Esempio n. 4
0
    def test_dynamic_absorption_none_observed(self):
        input_ice = self.load_ice_input_fixture("ice_35_min_input")

        (carb_starts,
         carb_values,
         carb_absorptions
         ) = self.load_carb_entry_fixture()

        carb_ratio_tuple = self.load_schedules()

        default_absorption_times = self.DEFAULT_ABSORPTION_TIMES

        carb_entry_starts = [carb_starts[2]]
        carb_entry_quantities = [carb_values[2]]
        carb_entry_absorptions = [carb_absorptions[2]]

        (expected_dates,
         expected_values
         ) = self.load_cob_output_fixture("ice_35_min_none_output")

        (absorptions,
         timelines,
         entries,  # pylint: disable=W0612
         ) = map_(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             *input_ice,
             *carb_ratio_tuple,
             self.INSULIN_SENSITIVITY_START_DATES,
             self.INSULIN_SENSITIVITY_END_DATES,
             self.INSULIN_SENSITIVITY_VALUES,
             default_absorption_times[1] / default_absorption_times[0],
             default_absorption_times[1],
             0
             )

        self.assertEqual(len(absorptions), 1)
        self.assertEqual(absorptions[0][6], 240)
        self.assertEqual(
            absorptions[0][4],
            datetime.fromisoformat("2015-10-15 23:00:00")
        )

        (cob_dates,
         cob_values
         ) = dynamic_carbs_on_board(
             carb_entry_starts,
             carb_entry_quantities,
             carb_entry_absorptions,
             absorptions,
             timelines,
             default_absorption_times[1],
             delay=10,
             delta=5,
             start=input_ice[0][0],
             end=(
                 input_ice[0][0]
                 + timedelta(hours=6)
                 )
             )

        assert len(expected_dates) == len(cob_dates)

        for i in range(0, len(expected_dates)):
            self.assertEqual(
                expected_dates[i], cob_dates[i]
            )
            self.assertAlmostEqual(
                expected_values[i], cob_values[i], 1
            )
Esempio n. 5
0
def get_carb_glucose_effects(carb_dates,
                             carb_values,
                             absorption_times,
                             at_date,
                             effect_starts,
                             effect_ends,
                             effect_values,
                             carb_ratio_starts,
                             carb_ratios,
                             sensitivity_starts,
                             sensitivity_ends,
                             sensitivity_values,
                             default_absorption_times,
                             absorption_time_overrun=1.5,
                             delay=10,
                             delta=5,
                             end_date=None):
    """ Retrieve a timeline of effect on blood glucose from carbohydrates

    Arguments:
    carb_dates -- list of times of carb entry (datetime objects)
    carb_values -- list of grams of carbs eaten
    absorption_times -- list of lengths of absorption times (mins)

    at_date -- the time to calculate the effect at (datetime object)

    effect_starts -- list of start times of carb effect (datetime objects)
    effect_ends -- list of end times of carb effect (datetime objects)
    effect_values -- list of glucose velocities (mg/dL)

    carb_ratio_starts -- list of start times of carb ratios (time objects)
    carb_ratios -- list of carb ratios (g/U)

    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)

    default_absorption_time -- absorption time to use for unspecified
                               carb entries

    absorption_time_overrun -- multiplier to determine absorption time
                               from the specified absorption time

    delay -- the time to delay the carb effect
    delta -- time interval between glucose values

    end_date -- date to end calculation of glucose effects

    Output:
    An array of effects in chronological order
    """
    assert len(carb_dates) == len(carb_values) == len(absorption_times),\
        "expected input shapes to match"

    assert len(effect_starts) == len(effect_ends) == len(effect_values),\
        "expected input shapes to match"

    if not carb_dates:
        return ([], [])

    maximum_absorption_time_interval = default_absorption_times[2] * 2

    # To know glucose effects at the requested start date, we need to fetch
    # samples that might still be absorbing
    food_start = at_date - timedelta(minutes=maximum_absorption_time_interval)

    filtered_carbs = filter_date_range_for_carbs(carb_dates, carb_values,
                                                 absorption_times, food_start,
                                                 end_date)

    # if we have counteraction effects, generate our carb glucose effects
    # with a dynamic model
    if effect_starts and effect_starts[0]:
        (absorption_results,
         timelines) = map_(*filtered_carbs, effect_starts, effect_ends,
                           effect_values, carb_ratio_starts, carb_ratios,
                           sensitivity_starts, sensitivity_ends,
                           sensitivity_values, absorption_time_overrun,
                           default_absorption_times[1], delay, delta)[0:2]

        effects = dynamic_glucose_effects(*filtered_carbs,
                                          absorption_results,
                                          timelines,
                                          carb_ratio_starts,
                                          carb_ratios,
                                          sensitivity_starts,
                                          sensitivity_ends,
                                          sensitivity_values,
                                          default_absorption_times[1],
                                          delay,
                                          delta,
                                          start=at_date,
                                          end=end_date,
                                          scaler=1.7)
    # otherwise, use a static model
    else:
        effects = carb_glucose_effects(*filtered_carbs, carb_ratio_starts,
                                       carb_ratios, sensitivity_starts,
                                       sensitivity_ends, sensitivity_values,
                                       default_absorption_times[1], delay,
                                       delta, at_date, end_date)

    assert len(effects[0]) == len(effects[1]), "expected output shape to match"

    return effects
Esempio n. 6
0
def get_carbs_on_board(carb_dates,
                       carb_values,
                       absorption_times,
                       at_date,
                       effect_starts,
                       effect_ends,
                       effect_values,
                       carb_ratio_starts,
                       carb_ratios,
                       sensitivity_starts,
                       sensitivity_ends,
                       sensitivity_values,
                       default_absorption_times,
                       absorption_time_overrun=1.5,
                       delay=10,
                       delta=5,
                       end_date=None):
    """ Retrieves the COB at a time, or a timeline of COB

    Arguments:
    carb_dates -- list of times of carb entry (datetime objects)
    carb_values -- list of grams of carbs eaten
    absorption_times -- list of lengths of absorption times (mins)

    at_date -- the time to calculate the COB at (datetime object)

    effect_starts -- list of start times of carb effect (datetime objects)
    effect_ends -- list of end times of carb effect (datetime objects)
    effect_values -- list of glucose velocities (mg/dL)

    carb_ratio_starts -- list of start times of carb ratios (time objects)
    carb_ratios -- list of carb ratios (g/U)

    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)

    default_absorption_times -- list absorption times to use for unspecified
                               carb entries in format [fast, medium, slow]

    absorption_time_overrun -- multiplier to determine absorption time
                               from the specified absorption time

    delay -- the time to delay the COB
    delta -- time interval between glucose values

    end_date -- date to end calculation of COB

    Output:
    COB timeline
    """
    assert len(carb_dates) == len(carb_values) == len(absorption_times),\
        "expected input shapes to match"

    assert len(effect_starts) == len(effect_ends) == len(effect_values),\
        "expected input shapes to match"

    if not carb_dates:
        return ([], [])

    start_date = at_date - timedelta(minutes=delta)

    maximum_absorption_time_interval = default_absorption_times[2] * 2

    # To know COB at the requested start date, we need to fetch samples that
    # might still be absorbing
    food_start = start_date - timedelta(
        minutes=maximum_absorption_time_interval)

    filtered_carbs = filter_date_range_for_carbs(carb_dates, carb_values,
                                                 absorption_times, food_start,
                                                 end_date)

    # If we have counteraction effects, use a dynamic model
    if (effect_starts and effect_starts[0] and carb_ratio_starts
            and sensitivity_starts):
        (absorption_results,
         timelines) = map_(*filtered_carbs, effect_starts, effect_ends,
                           effect_values, carb_ratio_starts, carb_ratios,
                           sensitivity_starts, sensitivity_ends,
                           sensitivity_values, absorption_time_overrun,
                           default_absorption_times[1], delay, delta)[0:2]

        cob_data = dynamic_carbs_on_board(*filtered_carbs,
                                          absorption_results,
                                          timelines,
                                          default_absorption_times[1],
                                          delay,
                                          delta,
                                          start=start_date,
                                          end=end_date,
                                          scaler=1.5)
    # otherwise, use a static model
    else:
        cob_data = carbs_on_board(*filtered_carbs,
                                  default_absorption_times[1],
                                  delay,
                                  delta,
                                  start=start_date,
                                  end=end_date)

    return cob_data