Skip to content

Commit 36da082

Browse files
committed
Merge pull request #34 from loudnate/dev
Version 0.0.6
2 parents 1171ad4 + d7ed1da commit 36da082

File tree

4 files changed

+113
-14
lines changed

4 files changed

+113
-14
lines changed

openapscontrib/predict/__init__.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ def get_program(params):
307307
"""
308308
args = (
309309
_json_file(params['history']),
310-
params.get('insulin_action_curve', None) or
311-
_opt_json_file(params.get('settings', ''))['insulin_action_curve'],
310+
int(params.get('insulin_action_curve', None) or
311+
_opt_json_file(params.get('settings', ''))['insulin_action_curve']),
312312
Schedule(_json_file(params['insulin_sensitivities'])['sensitivities'])
313313
)
314314

@@ -317,7 +317,7 @@ def get_program(params):
317317
)
318318

319319
if params.get('absorption_delay'):
320-
kwargs.update(absorption_delay=params.get('absorption_delay'))
320+
kwargs.update(absorption_delay=int(params.get('absorption_delay')))
321321

322322
return args, kwargs
323323

@@ -367,12 +367,32 @@ def configure_app(app, parser):
367367
help='The delay time between a dosing event and when absorption begins'
368368
)
369369

370+
parser.add_argument(
371+
'--start-at',
372+
nargs=argparse.OPTIONAL,
373+
help='File containing the timestamp at which to truncate the beginning of the output, '
374+
'as a JSON-encoded ISO date'
375+
)
376+
377+
parser.add_argument(
378+
'--end-at',
379+
nargs=argparse.OPTIONAL,
380+
help='File containing the timestamp at which to truncate the end of the output, '
381+
'as a JSON-encoded ISO date'
382+
)
383+
370384
def get_params(self, args):
371385
params = super(walsh_iob, self).get_params(args)
372386

373387
args_dict = dict(**args.__dict__)
374388

375-
for key in ('history', 'settings', 'insulin_action_curve', 'basal_dosing_end', 'absorption_delay'):
389+
for key in ('history',
390+
'settings',
391+
'insulin_action_curve',
392+
'basal_dosing_end',
393+
'absorption_delay',
394+
'start_at',
395+
'end_at'):
376396
value = args_dict.get(key)
377397
if value is not None:
378398
params[key] = value
@@ -390,16 +410,18 @@ def get_program(params):
390410
"""
391411
args = (
392412
_json_file(params['history']),
393-
params.get('insulin_action_curve', None) or
394-
_opt_json_file(params.get('settings', ''))['insulin_action_curve']
413+
int(params.get('insulin_action_curve', None) or
414+
_opt_json_file(params.get('settings', ''))['insulin_action_curve'])
395415
)
396416

397417
kwargs = dict(
398-
basal_dosing_end=_opt_date(_opt_json_file(params.get('basal_dosing_end')))
418+
basal_dosing_end=_opt_date(_opt_json_file(params.get('basal_dosing_end'))),
419+
start_at=_opt_date(_opt_json_file(params.get('start_at'))),
420+
end_at=_opt_date(_opt_json_file(params.get('end_at')))
399421
)
400422

401423
if params.get('absorption_delay'):
402-
kwargs.update(absorption_delay=params.get('absorption_delay'))
424+
kwargs.update(absorption_delay=int(params.get('absorption_delay')))
403425

404426
return args, kwargs
405427

@@ -591,8 +613,8 @@ def get_program(self, params):
591613
args = (
592614
_json_file(params['pump-history']),
593615
recent_glucose,
594-
params.get('insulin_action_curve', None) or
595-
_opt_json_file(params.get('settings', ''))['insulin_action_curve'],
616+
int(params.get('insulin_action_curve', None) or
617+
_opt_json_file(params.get('settings', ''))['insulin_action_curve']),
596618
Schedule(_json_file(params['insulin_sensitivities'])['sensitivities']),
597619
Schedule(_json_file(params['carb_ratios'])['schedule']),
598620
)

openapscontrib/predict/predict.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,9 @@ def calculate_iob(
496496
insulin_action_curve,
497497
dt=5,
498498
absorption_delay=10,
499-
basal_dosing_end=None
499+
basal_dosing_end=None,
500+
start_at=None,
501+
end_at=None
500502
):
501503
"""Calculates insulin on board degradation according to Walsh's algorithm, from the latest history entry until 0
502504
@@ -510,6 +512,10 @@ def calculate_iob(
510512
:type absorption_delay: int
511513
:param basal_dosing_end: A datetime at which continuing doses should be assumed to be cancelled
512514
:type basal_dosing_end: datetime.datetime
515+
:param start_at: A datetime override at which to begin the output
516+
:type start_at: datetime.datetime
517+
:param end_at: A datetime override at which to end the output
518+
:type end_at: datetime.datetime
513519
:return: A list of IOB values and their timestamps
514520
:rtype: list(dict)
515521
"""
@@ -519,8 +525,8 @@ def calculate_iob(
519525
first_history_event = sorted(normalized_history, key=lambda e: e['start_at'])[0]
520526
last_history_event = sorted(normalized_history, key=lambda e: e['end_at'])[-1]
521527
last_history_datetime = ceil_datetime_at_minute_interval(parse(last_history_event['end_at']), dt)
522-
simulation_start = floor_datetime_at_minute_interval(parse(first_history_event['start_at']), dt)
523-
simulation_end = last_history_datetime + datetime.timedelta(minutes=(insulin_action_curve * 60 + absorption_delay))
528+
simulation_start = start_at or floor_datetime_at_minute_interval(parse(first_history_event['start_at']), dt)
529+
simulation_end = end_at or last_history_datetime + datetime.timedelta(minutes=(insulin_action_curve * 60 + absorption_delay))
524530

525531
insulin_duration_minutes = insulin_action_curve * 60.0
526532

openapscontrib/predict/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.0.5'
1+
__version__ = '0.0.6'

tests/predict_tests.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,77 @@ def test_complicated_history(self):
10851085
self.assertDictContainsSubset({'date': '2015-10-16T02:40:00', 'unit': 'U'}, effect[-1])
10861086
self.assertAlmostEqual(0, effect[-1]['amount'], delta=0.01)
10871087

1088+
def test_start_at(self):
1089+
with open(get_file_at_path("fixtures/normalize_history.json")) as fp:
1090+
normalized_history = json.load(fp)
1091+
1092+
effect = calculate_iob(
1093+
normalized_history,
1094+
4,
1095+
start_at=datetime(2015, 10, 15, 22, 11, 00)
1096+
)
1097+
1098+
self.assertDictContainsSubset({'date': '2015-10-15T22:11:00', 'unit': 'U'}, effect[0])
1099+
self.assertAlmostEqual(8.30, effect[0]['amount'], delta=0.01)
1100+
self.assertDictContainsSubset({'date': '2015-10-16T02:41:00', 'unit': 'U'}, effect[-1])
1101+
self.assertAlmostEqual(0, effect[-1]['amount'], delta=0.01)
1102+
1103+
def test_end_at(self):
1104+
with open(get_file_at_path("fixtures/normalize_history.json")) as fp:
1105+
normalized_history = json.load(fp)
1106+
1107+
effect = calculate_iob(
1108+
normalized_history,
1109+
4,
1110+
end_at=datetime(2015, 10, 15, 20, 11, 00)
1111+
)
1112+
1113+
self.assertDictEqual({'date': '2015-10-15T18:05:00', 'amount': 0.0, 'unit': 'U'}, effect[0])
1114+
self.assertDictContainsSubset({'date': '2015-10-15T18:10:00', 'unit': 'U'}, effect[1])
1115+
self.assertAlmostEqual(0.0, effect[1]['amount'], delta=0.01)
1116+
self.assertDictContainsSubset({'date': '2015-10-15T18:20:00', 'unit': 'U'}, effect[3])
1117+
self.assertAlmostEqual(-0.02, effect[3]['amount'], delta=0.01)
1118+
self.assertDictContainsSubset({'date': '2015-10-15T19:05:00', 'unit': 'U'}, effect[12])
1119+
self.assertAlmostEqual(-0.47, effect[12]['amount'], delta=0.01)
1120+
self.assertDictContainsSubset({'date': '2015-10-15T20:15:00', 'unit': 'U'}, effect[-1])
1121+
self.assertAlmostEqual(9.26, effect[-1]['amount'], delta=0.01)
1122+
1123+
def test_start_at_end_at(self):
1124+
with open(get_file_at_path("fixtures/normalize_history.json")) as fp:
1125+
normalized_history = json.load(fp)
1126+
1127+
effect = calculate_iob(
1128+
normalized_history,
1129+
4,
1130+
start_at=datetime(2015, 10, 15, 22, 11, 00),
1131+
end_at=datetime(2015, 10, 16, 00, 01, 50)
1132+
)
1133+
1134+
self.assertDictContainsSubset({'date': '2015-10-15T22:11:00', 'unit': 'U'}, effect[0])
1135+
self.assertAlmostEqual(8.30, effect[0]['amount'], delta=0.01)
1136+
self.assertDictContainsSubset({'date': '2015-10-16T00:06:00', 'unit': 'U'}, effect[-1])
1137+
self.assertAlmostEqual(2.53, effect[-1]['amount'], delta=0.01)
1138+
1139+
def test_single_entry(self):
1140+
with open(get_file_at_path("fixtures/normalize_history.json")) as fp:
1141+
normalized_history = json.load(fp)
1142+
1143+
effect = calculate_iob(
1144+
normalized_history,
1145+
4,
1146+
start_at=datetime(2015, 10, 15, 22, 11, 00),
1147+
end_at=datetime(2015, 10, 15, 22, 11, 00)
1148+
)
1149+
1150+
self.assertListEqual(
1151+
[{
1152+
'date': '2015-10-15T22:11:00',
1153+
'unit': 'U',
1154+
'amount': 8.306
1155+
}],
1156+
[e.update({'amount': round(e['amount'], 3)}) or e for e in effect]
1157+
)
1158+
10881159

10891160
class CalculateGlucoseFromEffectsTestCase(unittest.TestCase):
10901161
@classmethod

0 commit comments

Comments
 (0)