Modified Master to replace profile sens with Chris Wilson's Dynamic ISF in OpenAPSSMB.

The rule of 277700 ISF using current BG is used for all predictions, while for dosing, if delta is =0 r positive, current bg is used, however, if delta is -ve, future bg is used.
This commit is contained in:
t_j_s 2022-02-12 18:45:36 +00:00
parent 34c4dc2a98
commit f98175755e
3 changed files with 153 additions and 33 deletions

View file

@ -277,16 +277,50 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
var profile_sens = round(profile.sens,1)
var sens = profile.sens;
if (typeof autosens_data !== 'undefined' && autosens_data) {
sens = profile.sens / sensitivityRatio;
sens = round(sens, 1);
if (sens !== profile_sens) {
console.log("ISF from "+profile_sens+" to "+sens);
} else {
console.log("ISF unchanged: "+sens);
var now = new Date().getHours();
if (now < 1){
now = 1;}
else {
console.error("Time now is "+now+"; ");
}
//console.log(" (autosens ratio "+sensitivityRatio+")");
var tdd7 = meal_data.TDDAIMI7;
var tdd_pump_now = meal_data.TDDPUMP;
var tdd_pump = ( tdd_pump_now / (now / 24));
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; ";
}
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+"; ";
}
else {
console.log("TDD 7 ="+tdd7+", TDD Pump ="+tdd_pump+" and TDD = "+TDD+";");
rT.reason += "TDD: " +TDD+ " based on standard pump 60/tdd7 40 split; ";
}
var variable_sens = (277700 / (TDD * bg));
variable_sens = round(variable_sens,1);
console.log("Current sensitivity for predictions is " +variable_sens+" based on current bg");
sens = variable_sens;
if ( high_temptarget_raises_sensitivity && profile.temptargetSet && target_bg > normalTarget || profile.low_temptarget_lowers_sensitivity && profile.temptargetSet && target_bg < normalTarget ) {
sens = sens / sensitivityRatio ;
sens = round(sens, 1);
console.log("ISF from "+variable_sens+" to "+sens+ "due to temp target; ");
} else {
sens = sens;
sens = round(sens, 1);
}
console.error("; CR:",profile.carb_ratio);
// compare currenttemp to iob_data.lastTemp and cancel temp if they don't match
@ -700,6 +734,20 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
console.error("UAM Impact:",uci,"mg/dL per 5m; UAM Duration:",UAMduration,"hours");
console.log("EventualBG is" +eventualBG+" ;");
if( glucose_status.delta >= 0 || bg > 60 && glucose_status.delta < 2 && glucose_status.delta > -2 && glucose_status.short_avgdelta > -2 && glucose_status.short_avgdelta < 2 ) {
var future_sens = ( 277700 / (TDD * bg) );
console.log("Future state sensitivity is " +future_sens+" using current bg due to no COB & small delta or variation");
rT.reason += "Dosing sensitivity: " +future_sens+" using current BG;";
}
else {
var future_sens = ( 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;";
}
var future_sens = round(future_sens,1);
minIOBPredBG = Math.max(39,minIOBPredBG);
minCOBPredBG = Math.max(39,minCOBPredBG);
@ -928,22 +976,25 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
}
}
// calculate 30m low-temp required to get projected BG up to target
// multiply by 2 to low-temp faster for increased hypo safety
var insulinReq = 2 * Math.min(0, (eventualBG - target_bg) / sens);
insulinReq = round( insulinReq , 2);
// calculate naiveInsulinReq based on naive_eventualBG
var naiveInsulinReq = Math.min(0, (naive_eventualBG - target_bg) / sens);
naiveInsulinReq = round( naiveInsulinReq , 2);
if (minDelta < 0 && minDelta > expectedDelta) {
// if we're barely falling, newinsulinReq should be barely negative
var newinsulinReq = round(( insulinReq * (minDelta / expectedDelta) ), 2);
//console.error("Increasing insulinReq from " + insulinReq + " to " + newinsulinReq);
insulinReq = newinsulinReq;
}
// rate required to deliver insulinReq less insulin over 30m:
var rate = basal + (2 * insulinReq);
rate = round_basal(rate, profile);
// calculate 30m low-temp required to get projected BG up to target
// multiply by 2 to low-temp faster for increased hypo safety
var insulinReq = 2 * Math.min(0, (eventualBG - target_bg) / future_sens);
insulinReq = round( insulinReq , 2);
// calculate naiveInsulinReq based on naive_eventualBG
var naiveInsulinReq = Math.min(0, (naive_eventualBG - target_bg) / sens);
naiveInsulinReq = round( naiveInsulinReq , 2);
if (minDelta < 0 && minDelta > expectedDelta) {
// if we're barely falling, newinsulinReq should be barely negative
var newinsulinReq = round(( insulinReq * (minDelta / expectedDelta) ), 2);
//console.error("Increasing insulinReq from " + insulinReq + " to " + newinsulinReq);
insulinReq = newinsulinReq;
}
// rate required to deliver insulinReq less insulin over 30m:
var rate = basal + (2 * insulinReq);
rate = round_basal(rate, profile);
// if required temp < existing temp basal
var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60;
@ -1031,14 +1082,14 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
}
} else { // otherwise, calculate 30m high-temp required to get projected BG down to target
// insulinReq is the additional insulin required to get minPredBG down to target_bg
//console.error(minPredBG,eventualBG);
insulinReq = round( (Math.min(minPredBG,eventualBG) - target_bg) / sens, 2);
// if that would put us over max_iob, then reduce accordingly
if (insulinReq > max_iob-iob_data.iob) {
rT.reason += "max_iob " + max_iob + ", ";
insulinReq = max_iob-iob_data.iob;
}
// insulinReq is the additional insulin required to get minPredBG down to target_bg
//console.error(minPredBG,eventualBG);
insulinReq = round( (Math.min(minPredBG,eventualBG) - target_bg) / future_sens, 2);
// if that would put us over max_iob, then reduce accordingly
if (insulinReq > max_iob-iob_data.iob) {
rT.reason += "max_iob " + max_iob + ", ";
insulinReq = max_iob-iob_data.iob;
}
// rate required to deliver insulinReq more insulin over 30m:
rate = basal + (2 * insulinReq);

View file

@ -4,6 +4,8 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.MealData
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
@ -18,8 +20,11 @@ import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.shared.SafeParse
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.stats.TddCalculator
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONArray
import org.json.JSONException
@ -40,6 +45,10 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var dateUtil: DateUtil
//@Inject lateinit var danaPump: DanaPump
private var profile = JSONObject()
private var mGlucoseStatus = JSONObject()
@ -51,6 +60,11 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
private var smbAlwaysAllowed = false
private var currentTime: Long = 0
private var saveCgmSource = false
private var lastBolusNormalTime: Long = 0
private val millsToThePast = T.hours(4).msecs()
private var tddAIMI: TddCalculator? = null
var currentTempParam: String? = null
private set
var iobDataParam: String? = null
@ -241,6 +255,7 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
} else {
mGlucoseStatus.put("delta", glucoseStatus.delta)
}
mGlucoseStatus.put("short_avgdelta", glucoseStatus.shortAvgDelta)
mGlucoseStatus.put("long_avgdelta", glucoseStatus.longAvgDelta)
mGlucoseStatus.put("date", glucoseStatus.date)
@ -249,7 +264,13 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
this.mealData.put("slopeFromMaxDeviation", mealData.slopeFromMaxDeviation)
this.mealData.put("slopeFromMinDeviation", mealData.slopeFromMinDeviation)
this.mealData.put("lastBolusTime", mealData.lastBolusTime)
this.mealData.put("lastBolusNormalTime", lastBolusNormalTime)
this.mealData.put("lastCarbTime", mealData.lastCarbTime)
tddAIMI = TddCalculator(aapsLogger,rh,activePlugin,profileFunction,dateUtil,iobCobCalculator, repository)
this.mealData.put("TDD_AIMI7", tddAIMI!!.averageTDD(tddAIMI!!.calculate(7)).totalAmount)
this.mealData.put("TDDPUMP", tddAIMI!!.calculateDaily().totalAmount)
if (constraintChecker.isAutosensModeEnabled().value()) {
autosensData.put("ratio", autosensDataRatio)
} else {

View file

@ -76,7 +76,55 @@ class TddCalculator @Inject constructor(
return result
}
private fun averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose {
fun calculateDaily():TotalDailyDose {
val startTime = MidnightTime.calc(dateUtil.now() )
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 averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose {
val totalTdd = TotalDailyDose(timestamp = dateUtil.now())
for (i in 0 until tdds.size()) {
val tdd = tdds.valueAt(i)