Prep for Nightscout Dev upload.

1. DYnamic ISF Plugin uses combination of 8 hour weighted average, last full day and 7 day average TDDs.
2. Model is the reworked 1800 rule using log values and insulin peak.

LGS Threshold moved in preferences to the DynamicISF prefs module and only available in the Dynamic ISF plugin.
This commit is contained in:
t_j_s 2022-06-13 20:35:08 +01:00
parent 7fac5a87f3
commit c233f9ba12
5 changed files with 204 additions and 37 deletions

View file

@ -218,7 +218,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
//*********************************************************************************
console.error("---------------------------------------------------------");
console.error( " Dynamic ISF version Beta 1.5 ");
console.error( " Dynamic ISF version Beta 1.6.4 ");
console.error("---------------------------------------------------------");
@ -247,39 +247,48 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
/*var tdd_pump_now = meal_data.TDDPUMP;
var tdd_pump = ( tdd_pump_now / (now / 24));*/
var TDD = (tdd7 * 0.4) + (tdd_pump * 0.6);
//var TDD = (tdd7 * 0.4) + (tdd_pump * 0.6);
console.error("Pump extrapolated TDD = "+tdd_pump+"; ");
//if (tdd7 > 0){
if ( tdd_pump > tdd7 && now < 5 || now < 7 && TDD < ( 0.8 * tdd7 ) ){
TDD = ( 0.8 * tdd7 );
console.log("Excess or too low insulin from pump so TDD set to "+TDD+" based on 75% of TDD7; ");
rT.reason += "TDD: " +TDD+ " due to low or high tdd from pump; ";
}
var tdd1 = meal_data.TDDAIMI1;
var tdd_4 = meal_data.TDDLast4;
var tdd8to4 = meal_data.TDD4to8;
var tdd_last8_wt = ( ( ( 1.4 * tdd_4) + ( 0.6 * tdd8to4) ) * 3 );
else if (tdd_pump > (1.75 * tdd7)){
TDD = tdd7;
console.error("TDD set to TDD7 due to high pump usage reported. TDD = "+TDD+"; ");
rT.reason += "TDD set to TDD7 due to high pump usage reported. TDD = "+TDD+"; ";
}
console.error("Rolling 8 hours weight average: "+tdd_last8_wt+"; ");
console.error("1-day average TDD is: "+tdd1+"; ");
console.error("7-day average TDD is: " +tdd7+ "; ");
//TDD = ( tdd_last8_wt * 0.6) + ( tdd7 * 0.4 );
var TDD = ( tdd_last8_wt * 0.33 ) + ( tdd7 * 0.34 ) + (tdd1 * 0.33);
console.log("TDD = " +TDD+ " using average of 7-day, 1-day and weighted 8hr average");
else if (tdd_pump < (0.33 * tdd7)){
TDD = (tdd7 * 0.25) + (tdd_pump * 0.75);
console.error("TDD weighted to pump due to low insulin usage. TDD = "+TDD+"; ");
rT.reason += "TDD weighted to pump due to low insulin usage. TDD = "+TDD+"; ";
}
//var ins_val = 75;
var insulin = profile.insulinType;
console.log("Insulin Peak = "+profile.insulinPeak+"; ");
//console.log("Initial insulin value for ISF: "+ins_val+"; ");
//console.log("Current value for insulin: "+insulin+"; ");
else {
console.log("TDD = " +TDD+ " based on standard pump 60/tdd7 40 split; ");
rT.reason += "TDD: " +TDD+ " based on standard pump 60/tdd7 40 split; ";
}
var ins_val = 75; // Lyumjev peak: 75
if (profile.insulinPeak > 65) { // lyumjev peak: 45
ins_val = 55;
} else if (profile.insulinPeak > 50 ){ // ultra rapid peak: 55
ins_val = 65;
}
console.log("For "+profile.insulinType+" (insulin peak: "+profile.insulinPeak+") divisor is: "+ins_val+"; ");
console.log("Insulin value for ISF based on profile: "+ins_val+"; ");
var dynISFadjust = profile.DynISFAdjust;
var dynISFadjust = ( dynISFadjust / 100 );
var TDD = (dynISFadjust * TDD);
var variable_sens = (277700 / ( TDD * bg));
dynISFadjust = ( dynISFadjust / 100 );
TDD = ( dynISFadjust * TDD );
var variable_sens = 1800 / ( TDD * (Math.log(( bg / ins_val ) + 1 ) ) );
variable_sens = round(variable_sens,1);
if (dynISFadjust > 1 ) {
console.log("TDD adjustment factor is: " +dynISFadjust+"; ");
console.log("TDD adjusted to "+TDD+" using adjustment factor of "+dynISFadjust+"; ");
@ -314,7 +323,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
console.log("ISF from "+variable_sens+" to "+sens+ "due to temp target; ");
}
else {
sensitivityRatio = ( tdd_24 / tdd7 );
sensitivityRatio = ( meal_data.TDD24 / tdd7 );
}
if (sensitivityRatio > 1) {
sensitivityRatio = Math.min(sensitivityRatio, profile.autosens_max);
@ -501,9 +510,41 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return rT;
}
// min_bg of 90 -> threshold of 65, 100 -> 70 110 -> 75, and 130 -> 85
var threshold = min_bg - 0.5*(min_bg-40);
// min_bg of 90 -> threshold of 65, 100 -> 70 110 -> 75, and 130 -> 85, or if specified by user, take that value
var lgsThreshold = profile.lgsThreshold;
console.error("Profile LGS Threshold set to"+lgsThreshold+"; ");
//if(lgsThreshold < 5.6)
if(lgsThreshold > 3.2 && lgsThreshold < 5.6){
lgsThreshold = (18 * lgsThreshold);
lgsThreshold = round(lgsThreshold, 2);
console.error("LGS Threshold converted to"+lgsThreshold+"; ");
}else{
lgsThreshold;
}
var threshold = min_bg - 0.5*(min_bg-40);
var oldThreshold = threshold;
if(lgsThreshold < 65 || lgsThreshold > 120) {
threshold;
}
else if( lgsThreshold < threshold){
threshold;
}
else {
threshold = lgsThreshold;
}
console.error("Threshold set from " + convert_bg(oldThreshold, profile) + " to " + convert_bg(threshold, profile) + "; ");
/*var oldThreshold = threshold;
if(lgsThreshold < 65 || lgsThreshold > 120) {
lgsThreshold = threshold;
}
else{
threshold = Math.max(threshold, lgsThreshold);
}
if( threshold === lgsThreshold ) {
console.log("Threshold set from " + convert_bg(oldThreshold, profile) + " to " + convert_bg(threshold, profile) + "; ")
}*/
//console.error(reservoir_data);
rT = {
@ -808,19 +849,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
console.log("EventualBG is" +eventualBG+" ;");
if (bg > target_bg && glucose_status.delta < 3 && glucose_status.delta > -3 && glucose_status.short_avgdelta > -3 && glucose_status.short_avgdelta < 3 && eventualBG > target_bg && eventualBG < bg ) {
var future_sens = ( 277700 / (TDD * ((eventualBG * 0.5) + (bg * 0.5) ) ) );
var future_sens = ( 1800 / (Math.log((((eventualBG * 0.5) + (bg * 0.5))/ins_val)+1)*TDD));
var future_sens_old = ( 277700 / (TDD * ((bg * 0.5) + (eventualBG * 0.5 ))));
console.log("Future state sensitivity is " +future_sens+" based on eventual and current bg due to flat glucose level above target");
rT.reason += "Dosing sensitivity: " +future_sens+" using eventual BG;";
}
else if( glucose_status.delta > 0 && eventualBG > target_bg ) {
var future_sens = ( 277700 / (TDD * bg) );
var future_sens = ( 1800 / (Math.log((bg/ins_val)+1)*TDD));
var future_sens_old = ( 277700 / (TDD * bg));
console.log("Future state sensitivity is " +future_sens+" using current bg due to small delta or variation");
rT.reason += "Dosing sensitivity: " +future_sens+" using current BG;";
}
else {
var future_sens = ( 277700 / (TDD * eventualBG) );
var future_sens = ( 1800 / (Math.log((eventualBG/ins_val)+1)*TDD));
var future_sens_old = ( 277700 / (TDD * eventualBG));
console.log("Future state sensitivity is " +future_sens+" based on eventual bg due to -ve delta");
rT.reason += "Dosing sensitivity: " +future_sens+" using eventual BG;";
}
@ -1085,7 +1129,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
}
if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) {
rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr. ";
rT.reason += ", temp " + currenttemp.rate + " ~< req " + round(rate, 2) + "U/hr. ";
return rT;
} else {
// calculate a long enough zero temp to eventually correct back up to target
@ -1106,7 +1150,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp);
}
} else {
rT.reason += ", setting " + rate + "U/hr. ";
rT.reason += ", setting " + round(rate, 2) + "U/hr. ";
}
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
}

View file

@ -192,6 +192,11 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.profile.put("sens", profile.getIsfMgdl())
this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3))
this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
this.profile.put("lgsThreshold", sp.getDouble(R.string.key_treatmentssafety_lgsThreshold, 60.0))
val insulin = activePlugin.activeInsulin
val insulinType = insulin.friendlyName
val insulinPeak = insulin.peak
//mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity));
this.profile.put("high_temptarget_raises_sensitivity", sp.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity))
@ -223,6 +228,8 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.profile.put("maxSMBBasalMinutes", sp.getInt(R.string.key_smbmaxminutes, SMBDefaults.maxSMBBasalMinutes))
this.profile.put("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes))
this.profile.put("DynISFAdjust", SafeParse.stringToDouble(sp.getString(R.string.key_DynISFAdjust,"100")))
this.profile.put("insulinType", insulinType)
this.profile.put("insulinPeak", insulinPeak)
this.profile.put("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes))
//set the min SMB amount to be the amount set by the pump.
this.profile.put("bolus_increment", pumpBolusStep)
@ -263,9 +270,13 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.mealData.put("lastBolusTime", mealData.lastBolusTime)
this.mealData.put("lastCarbTime", mealData.lastCarbTime)
this.mealData.put("TDDAIMI1", tddCalculator.averageTDD(tddCalculator.calculate(1))?.totalAmount)
this.mealData.put("TDDAIMI7", tddCalculator.averageTDD(tddCalculator.calculate(7))?.totalAmount)
this.mealData.put("TDDPUMP", tddCalculator.calculateDaily().totalAmount)
this.mealData.put("TDDLast24", tddCalculator.calculate24Daily().totalAmount)
this.mealData.put("TDDLast4", tddCalculator.calculate4Daily().totalAmount)
this.mealData.put("TDD4to8", tddCalculator.calculate8Gap().totalAmount)
this.mealData.put("TDD24", tddCalculator.calculate24Daily().totalAmount)
if (constraintChecker.isAutosensModeEnabled().value()) {
autosensData.put("ratio", autosensDataRatio)

View file

@ -172,6 +172,102 @@ class TddCalculator @Inject constructor(
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd
}
fun calculate4Daily():TotalDailyDose {
val startTime = dateUtil.now() - T.hours(hour = 4).msecs()
val endTime = dateUtil.now()
val tdd = TotalDailyDose(timestamp = startTime)
//val result = TotalDailyDose()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING }
.forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.bolusAmount += t.amount
//result.put(midnight, tdd)
}
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount
//result.put(midnight, tdd)
}
val calculationStep = T.mins(5).msecs()
val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
for (t in startTime until endTime step calculationStep) {
//val midnight = MidnightTime.calc(t)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
tdd.basalAmount += absoluteRate / 60.0 * 5.0
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
// they are not included in TBRs
val eb = iobCobCalculator.getExtendedBolus(t)
val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
}
//result.put(midnight, tdd)
}
//for (i in 0 until tdd.size()) {
//val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd
}
fun calculate8Gap():TotalDailyDose {
val startTime = dateUtil.now() - T.hours(hour = 8).msecs()
val endTime = dateUtil.now() - T.hours(hour = 4).msecs()
val tdd = TotalDailyDose(timestamp = startTime)
//val result = TotalDailyDose()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING }
.forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.bolusAmount += t.amount
//result.put(midnight, tdd)
}
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount
//result.put(midnight, tdd)
}
val calculationStep = T.mins(5).msecs()
val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
for (t in startTime until endTime step calculationStep) {
//val midnight = MidnightTime.calc(t)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
tdd.basalAmount += absoluteRate / 60.0 * 5.0
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
// they are not included in TBRs
val eb = iobCobCalculator.getExtendedBolus(t)
val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
}
//result.put(midnight, tdd)
}
//for (i in 0 until tdd.size()) {
//val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd
}

View file

@ -58,6 +58,7 @@
<string name="treatmentssafety_title">Treatments safety</string>
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
<string name="treatmentssafety_maxcarbs_title">Max allowed carbs [g]</string>
<string name="treatmentssafety_lgsThreshold_title">BG level below which low glucose suspend occurs</string>
<string name="nav_preferences_plugin">%1$s Preferences</string>
<string name="nav_preferences">Preferences</string>
<string name="nav_refreshtreatments">Refresh treatments from NS</string>
@ -162,7 +163,10 @@
<string name="apsmode_title">APS Mode</string>
<string name="closedloop">Closed Loop</string>
<string name="openloop">Open Loop</string>
<string name="lowglucosesuspend">Low Glucose Suspend</string>
<string name="lowglucosesuspend">Low Glucose Suspend</string>
<string name="rapidacting">Humalog/Novolog</string>
<string name="Fiasp">Fiasp</string>
<string name="Lyumjev">Lyumjev</string>
<string name="disabledloop">Loop Disabled</string>
<string name="openloop_newsuggestion">New suggestion available</string>
<string name="carbssuggestion">Carbs Suggestion</string>
@ -701,6 +705,7 @@
<string name="smb_frequency_exceeded">A bolus was delivered within the last 3 minutes, skipping SMB</string>
<string name="basal_set_correctly">Basal set correctly</string>
<string name="key_treatmentssafety_maxbolus" translatable="false">treatmentssafety_maxbolus</string>
<string name="key_treatmentssafety_lgsThreshold" translatable="false">lgsThreshold</string>
<string name="limitingextendedbolus">Limiting extended bolus to %1$.1f U because of %2$s</string>
<string name="limitingcarbs">Limiting carbs to %1$d g because of %2$s</string>
<string name="limitingiob">Limiting IOB to %1$.1f U because of %2$s</string>
@ -720,6 +725,7 @@
<string name="openapssmb_maxiob_summary">This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value</string>
<string name="absorption_cutoff_title">Meal max absorption time [h]</string>
<string name="absorption_cutoff_summary">Time at which any meal is considered absorbed. Remaining carbs will be cut off.</string>
<string name="treatmentssafety_lgsThreshold_summary">BG value below which insulin is suspended. Default value uses standard target model. User can set value between 60mg/dl (3.3mmol/l) and 100mg/dl(5.5mmol/l). Values below 65/3.6 result in use of default model</string>
<string name="overview_show_notes_field_in_dialogs_title">Show notes field in treatment dialogs</string>
<string name="title_activity_setup_wizard" translatable="false">SetupWizardActivity</string>
<string name="next_button">Next</string>

View file

@ -39,6 +39,16 @@
validate:floatminNumber="1"
validate:testType="floatNumericRange" />
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
android:defaultValue="60"
android:inputType="numberDecimal"
android:dialogMessage="@string/treatmentssafety_lgsThreshold_summary"
android:key="@string/key_treatmentssafety_lgsThreshold"
android:title="@string/treatmentssafety_lgsThreshold_title"
validate:floatmaxNumber="100"
validate:floatminNumber="3.3"
validate:testType="floatNumericRange" />
<SwitchPreference
android:defaultValue="false"
android:key="openapsama_useautosens"