Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
bower_components/
node_modules/


bundle/bundle.out.js

.idea/
*.iml
my.env

*.env
static/bower_components/
.*.sw?
.DS_Store

.vagrant
/iisnode

# istanbul output
coverage/

npm-debug.log
190 changes: 19 additions & 171 deletions bin/oref0-calculate-iob.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,184 +18,32 @@

*/

function iobCalc(treatment, time, dia) {
var diaratio = dia / 3;
var peak = 75 ;
var end = 180 ;
//var sens = profile_data.sens;
if (typeof time === 'undefined') {
var time = new Date();
}

if (treatment.insulin) {
var bolusTime=new Date(treatment.date);
var minAgo=(time-bolusTime)/1000/60 * diaratio;

if (minAgo < 0) {
var iobContrib=0;
var activityContrib=0;
}
else if (minAgo < peak) {
var x = (minAgo/5 + 1);
var iobContrib=treatment.insulin*(1-0.001852*x*x+0.001852*x);
//var activityContrib=sens*treatment.insulin*(2/dia/60/peak)*minAgo;
var activityContrib=treatment.insulin*(2/dia/60/peak)*minAgo;
}
else if (minAgo < end) {
var x = (minAgo-peak)/5;
var iobContrib=treatment.insulin*(0.001323*x*x - .054233*x + .55556);
//var activityContrib=sens*treatment.insulin*(2/dia/60-(minAgo-peak)*2/dia/60/(60*dia-peak));
var activityContrib=treatment.insulin*(2/dia/60-(minAgo-peak)*2/dia/60/(60*dia-peak));
}
else {
var iobContrib=0;
var activityContrib=0;
}
return {
iobContrib: iobContrib,
activityContrib: activityContrib
};
}
else {
return '';
}
}
function iobTotal(treatments, time) {
var iob = 0;
var bolusiob = 0;
var activity = 0;
if (!treatments) return {};
//if (typeof time === 'undefined') {
//var time = new Date();
//}

treatments.forEach(function(treatment) {
if(treatment.date < time.getTime( )) {
var dia = profile_data.dia;
var tIOB = iobCalc(treatment, time, dia);
if (tIOB && tIOB.iobContrib) iob += tIOB.iobContrib;
if (tIOB && tIOB.activityContrib) activity += tIOB.activityContrib;
// keep track of bolus IOB separately for snoozes, but decay it three times as fast
if (treatment.insulin >= 0.2 && treatment.started_at) {
var bIOB = iobCalc(treatment, time, dia*2)
//console.log(treatment);
//console.log(bIOB);
if (bIOB && bIOB.iobContrib) bolusiob += bIOB.iobContrib;
}
}
});

return {
iob: iob,
activity: activity,
bolusiob: bolusiob
};
}

function calcTempTreatments() {
var tempHistory = [];
var tempBoluses = [];
var now = new Date();
var timeZone = now.toString().match(/([-\+][0-9]+)\s/)[1]
for (var i=0; i < pumpHistory.length; i++) {
var current = pumpHistory[i];
//if(pumpHistory[i].date < time) {
if (pumpHistory[i]._type == "Bolus") {
//console.log(pumpHistory[i]);
var temp = {};
temp.timestamp = current.timestamp;
//temp.started_at = new Date(current.date);
temp.started_at = new Date(current.timestamp + timeZone);
//temp.date = current.date
temp.date = temp.started_at.getTime();
temp.insulin = current.amount
tempBoluses.push(temp);
} else if (pumpHistory[i]._type == "TempBasal") {
if (current.temp == 'percent') {
continue;
}
var rate = pumpHistory[i].rate;
var date = pumpHistory[i].date;
if (i>0 && pumpHistory[i-1].date == date && pumpHistory[i-1]._type == "TempBasalDuration") {
var duration = pumpHistory[i-1]['duration (min)'];
} else if (i+1<pumpHistory.length && pumpHistory[i+1].date == date && pumpHistory[i+1]._type == "TempBasalDuration") {
var duration = pumpHistory[i+1]['duration (min)'];
} else { console.log("No duration found for "+rate+" U/hr basal"+date); }
var temp = {};
temp.rate = rate;
//temp.date = date;
temp.timestamp = current.timestamp;
//temp.started_at = new Date(temp.date);
temp.started_at = new Date(temp.timestamp + timeZone);
temp.date = temp.started_at.getTime();
temp.duration = duration;
tempHistory.push(temp);
}
//}
};
for (var i=0; i+1 < tempHistory.length; i++) {
if (tempHistory[i].date + tempHistory[i].duration*60*1000 > tempHistory[i+1].date) {
tempHistory[i].duration = (tempHistory[i+1].date - tempHistory[i].date)/60/1000;
}
}
var tempBolusSize;
var now = new Date();
var timeZone = now.toString().match(/([-\+][0-9]+)\s/)[1]
for (var i=0; i < tempHistory.length; i++) {
if (tempHistory[i].duration > 0) {
var netBasalRate = tempHistory[i].rate-profile_data.current_basal;
if (netBasalRate < 0) { tempBolusSize = -0.05; }
else { tempBolusSize = 0.05; }
var netBasalAmount = Math.round(netBasalRate*tempHistory[i].duration*10/6)/100
var tempBolusCount = Math.round(netBasalAmount / tempBolusSize);
var tempBolusSpacing = tempHistory[i].duration / tempBolusCount;
for (var j=0; j < tempBolusCount; j++) {
var tempBolus = {};
tempBolus.insulin = tempBolusSize;
tempBolus.date = tempHistory[i].date + j * tempBolusSpacing*60*1000;
tempBolus.created_at = new Date(tempBolus.date);
tempBoluses.push(tempBolus);
}
}
}
return [ ].concat(tempBoluses).concat(tempHistory);
return {
tempBoluses: tempBoluses,
tempHistory: tempHistory
};

}
var generate = require('oref0/lib/iob');

if (!module.parent) {
var iob_input = process.argv.slice(2, 3).pop()
var profile_input = process.argv.slice(3, 4).pop()
var clock_input = process.argv.slice(4, 5).pop()
var iob_input = process.argv.slice(2, 3).pop()
var profile_input = process.argv.slice(3, 4).pop()
var clock_input = process.argv.slice(4, 5).pop()

if (!iob_input || !profile_input) {
console.log('usage: ', process.argv.slice(0, 2), '<pumphistory.json> <profile.json> <clock.json>');
process.exit(1);
}
var cwd = process.cwd()
var all_data = require(cwd + '/' + iob_input);
var profile_data = require(cwd + '/' + profile_input);
var clock_data = require(cwd + '/' + clock_input);
var pumpHistory = all_data;
pumpHistory.reverse( );


var all_treatments = calcTempTreatments( );
//console.log(all_treatments);
var treatments = all_treatments; // .tempBoluses.concat(all_treatments.tempHistory);
treatments.sort(function (a, b) { return a.date > b.date });
//var lastTimestamp = new Date(treatments[treatments.length -1].date + 1000 * 60);
//console.log(clock_data);
var now = new Date();
var timeZone = now.toString().match(/([-\+][0-9]+)\s/)[1]
var clock_iso = clock_data + timeZone;
var clock = new Date(clock_iso);
//console.log(clock);
var iob = iobTotal(treatments, clock);
//var iobs = iobTotal(treatments, lastTimestamp);
// console.log(iobs);
var cwd = process.cwd()
var all_data = require(cwd + '/' + iob_input);
var profile_data = require(cwd + '/' + profile_input);
var clock_data = require(cwd + '/' + clock_input);

all_data.sort(function (a, b) { return a.date > b.date });

var inputs = {
history: all_data
, profile: profile_data
, clock: clock_data
};

var iob = generate(inputs);
console.log(JSON.stringify(iob));
}

113 changes: 14 additions & 99 deletions bin/oref0-get-profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,90 +16,7 @@

*/

function getTime(minutes) {
var baseTime = new Date();
baseTime.setHours('00');
baseTime.setMinutes('00');
baseTime.setSeconds('00');

return baseTime.getTime() + minutes * 60 * 1000;

}

/* Return basal rate(U / hr) at the provided timeOfDay */

function basalLookup() {
var now = new Date();
var basalRate = basalprofile_data[basalprofile_data.length-1].rate

for (var i = 0; i < basalprofile_data.length - 1; i++) {
if ((now >= getTime(basalprofile_data[i].minutes)) && (now < getTime(basalprofile_data[i + 1].minutes))) {
basalRate = basalprofile_data[i].rate;
break;
}
}
profile.current_basal= Math.round(basalRate*1000)/1000;
}

function bgTargetsLookup(){
var now = new Date();

//bgtargets_data.targets.sort(function (a, b) { return a.offset > b.offset });

var bgTargets = bgtargets_data.targets[bgtargets_data.targets.length - 1]

for (var i = 0; i < bgtargets_data.targets.length - 1; i++) {
if ((now >= getTime(bgtargets_data.targets[i].offset)) && (now < getTime(bgtargets_data.targets[i + 1].offset))) {
bgTargets = bgtargets_data.targets[i];
break;
}
}
// hard-code lower bounds for min_bg and max_bg in case pump is set too low, or units are wrong
profile.max_bg = max(100,bgTargets.high);
profile.min_bg = max(90,bgTargets.low);
// hard-code upper bound for min_bg in case pump is set too high
profile.min_bg = min(200,profile.min_bg);
}

function carbRatioLookup() {
var now = new Date();
//carbratio_data.schedule.sort(function (a, b) { return a.offset > b.offset });
var carbRatio = carbratio_data.schedule[carbratio_data.schedule.length - 1]

for (var i = 0; i < carbratio_data.schedule.length - 1; i++) {
if ((now >= getTime(carbratio_data.schedule[i].offset)) && (now < getTime(carbratio_data.schedule[i + 1].offset))) {
carbRatio = carbratio_data.schedule[i];
break;
}
}
profile.carbratio = carbRatio.ratio;
}

function isfLookup() {
var now = new Date();
//isf_data.sensitivities.sort(function (a, b) { return a.offset > b.offset });
var isfSchedule = isf_data.sensitivities[isf_data.sensitivities.length - 1]

for (var i = 0; i < isf_data.sensitivities.length - 1; i++) {
if ((now >= getTime(isf_data.sensitivities[i].offset)) && (now < getTime(isf_data.sensitivities[i + 1].offset))) {
isfSchedule = isf_data.sensitivities[i];
break;
}
}
profile.sens = isfSchedule.sensitivity;
}

function maxDailyBasal(){
basalprofile_data.sort(function (a, b) { if (a.rate < b.rate) { return 1 } if (a.rate > b.rate) { return -1; } return 0; });
profile.max_daily_basal = Math.round( basalprofile_data[0].rate *1000)/1000;
}

/*Return maximum daily basal rate(U / hr) from profile.basals */

function maxBasalLookup() {

profile.max_basal =pumpsettings_data.maxBasal;
}
var generate = require('oref0/lib/profile/');

if (!module.parent) {

Expand Down Expand Up @@ -127,23 +44,21 @@ if (!module.parent) {
var basalprofile_data = require(cwd + '/' + basalprofile_input);
var carbratio_data = require(cwd + '/' + carbratio_input);;

var profile = {
carbs_hr: 28 // TODO: verify this is completely unused and consider removing it if so
, max_iob: 0 // if max_iob.json is not profided, never give more insulin than the pump would have
, dia: pumpsettings_data.insulin_action_curve
, type: "current"
};

basalLookup();
maxDailyBasal();
maxBasalLookup()
bgTargetsLookup();
carbRatioLookup();
isfLookup();
var maxiob_data = { max_iob: 0 };
if (typeof maxiob_input != 'undefined') {
var maxiob_data = require(cwd + '/' + maxiob_input);
profile.max_iob = maxiob_data.max_iob;
maxiob_data = require(cwd + '/' + maxiob_input);
}
var inputs = {
settings: pumpsettings_data
, targets: bgtargets_data
, basals: basalprofile_data
, isf: isf_data
, max_iob: maxiob_data.max_iob || 0
, carbs: carbratio_data

};

var profile = generate(inputs);

console.log(JSON.stringify(profile));
}
Loading