copy old oref0 sensitivity code

This commit is contained in:
Milos Kozak 2017-06-24 15:04:22 +02:00
parent b39f59f59e
commit 70aaafa616
5 changed files with 266 additions and 109 deletions

View file

@ -215,6 +215,10 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
return activePump; return activePump;
} }
public static SensitivityInterface getActiveSensitivity() {
return activeSensitivity;
}
void logPluginStatus() { void logPluginStatus() {
for (PluginBase p : pluginList) { for (PluginBase p : pluginList) {
log.debug(p.getName() + ":" + log.debug(p.getName() + ":" +

View file

@ -7,11 +7,11 @@ import java.util.Date;
*/ */
public class AutosensData { public class AutosensData {
long time = 0L; public long time = 0L;
public String pastSensitivity = ""; public String pastSensitivity = "";
public double deviation = 0d; public double deviation = 0d;
boolean nonCarbsDeviation = false; boolean nonCarbsDeviation = false;
boolean nonEqualDeviation = false; public boolean nonEqualDeviation = false;
double absorbed = 0d; double absorbed = 0d;
public double carbsFromBolus = 0d; public double carbsFromBolus = 0d;
public double cob = 0; public double cob = 0;

View file

@ -29,6 +29,7 @@ import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.BasalData; import info.nightscout.androidaps.plugins.IobCobCalculator.events.BasalData;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
@ -55,9 +56,9 @@ public class IobCobCalculatorPlugin implements PluginBase {
private static Handler sHandler = null; private static Handler sHandler = null;
private static HandlerThread sHandlerThread = null; private static HandlerThread sHandlerThread = null;
private static Object dataLock = new Object(); private static final Object dataLock = new Object();
static IobCobCalculatorPlugin plugin = null; private static IobCobCalculatorPlugin plugin = null;
public static IobCobCalculatorPlugin getPlugin() { public static IobCobCalculatorPlugin getPlugin() {
if (plugin == null) if (plugin == null)
@ -65,6 +66,14 @@ public class IobCobCalculatorPlugin implements PluginBase {
return plugin; return plugin;
} }
public static LongSparseArray<AutosensData> getAutosensDataTable() {
return autosensDataTable;
}
public static List<BgReading> getBucketedData() {
return bucketed_data;
}
@Override @Override
public int getType() { public int getType() {
return GENERAL; return GENERAL;
@ -120,7 +129,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
} }
public IobCobCalculatorPlugin() { IobCobCalculatorPlugin() {
MainApp.bus().register(this); MainApp.bus().register(this);
if (sHandlerThread == null) { if (sHandlerThread == null) {
sHandlerThread = new HandlerThread(IobCobCalculatorPlugin.class.getSimpleName()); sHandlerThread = new HandlerThread(IobCobCalculatorPlugin.class.getSimpleName());
@ -198,14 +207,14 @@ public class IobCobCalculatorPlugin implements PluginBase {
} }
} }
public void createBucketedData() { private void createBucketedData() {
if (isAbout5minData()) if (isAbout5minData())
createBucketedData5min(); createBucketedData5min();
else else
createBucketedDataRecalculated(); createBucketedDataRecalculated();
} }
public void createBucketedDataRecalculated() { private void createBucketedDataRecalculated() {
synchronized (dataLock) { synchronized (dataLock) {
if (bgReadings == null || bgReadings.size() < 3) { if (bgReadings == null || bgReadings.size() < 3) {
bucketed_data = null; bucketed_data = null;
@ -310,7 +319,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
//log.debug("Releasing createBucketedData"); //log.debug("Releasing createBucketedData");
} }
public void calculateSensitivityData() { private void calculateSensitivityData() {
if (MainApp.getConfigBuilder() == null) if (MainApp.getConfigBuilder() == null)
return; // app still initializing return; // app still initializing
//log.debug("Locking calculateSensitivityData"); //log.debug("Locking calculateSensitivityData");
@ -523,106 +532,10 @@ public class IobCobCalculatorPlugin implements PluginBase {
} }
} }
public static AutosensResult detectSensitivity(long fromTime, long toTime) { private static AutosensResult detectSensitivity(long fromTime, long toTime) {
String age = SP.getString(R.string.key_age, ""); return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
int defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_adult))) defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) defaultHours = 4;
if (age.equals(MainApp.sResources.getString(R.string.key_child))) defaultHours = 4;
int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours);
long now = System.currentTimeMillis();
if (autosensDataTable == null || autosensDataTable.size() < 4) {
log.debug("No autosens data available");
return new AutosensResult();
}
AutosensData current = getAutosensData(toTime);
if (current == null) {
log.debug("No autosens data available");
return new AutosensResult();
}
List<Double> deviationsArray = new ArrayList<>();
String pastSensitivity = "";
int index = 0;
while (index < autosensDataTable.size()) {
AutosensData autosensData = autosensDataTable.valueAt(index);
if (autosensData.time < fromTime) {
index++;
continue;
}
if (autosensData.time > toTime) {
index++;
continue;
}
if (autosensData.time > now - hoursForDetection * 60 * 60 * 1000L)
deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d);
if (deviationsArray.size() > hoursForDetection * 60 / 5)
deviationsArray.remove(0);
pastSensitivity += autosensData.pastSensitivity;
int secondsFromMidnight = Profile.secondsFromMidnight(autosensData.time);
if (secondsFromMidnight % 3600 < 2.5 * 60 || secondsFromMidnight % 3600 > 57.5 * 60) {
pastSensitivity += "(" + Math.round(secondsFromMidnight / 3600d) + ")";
}
index++;
}
Double[] deviations = new Double[deviationsArray.size()];
deviations = deviationsArray.toArray(deviations);
Profile profile = MainApp.getConfigBuilder().getProfile();
double sens = profile.getIsf();
String ratioLimit = "";
String sensResult = "";
log.debug("Records: " + index + " " + pastSensitivity);
Arrays.sort(deviations);
double percentile = percentile(deviations, 0.50);
double basalOff = percentile * (60 / 5) / Profile.toMgdl(sens, profile.getUnits());
double ratio = 1 + (basalOff / profile.getMaxDailyBasal());
if (percentile < 0) { // sensitive
sensResult = "Excess insulin sensitivity detected";
} else if (percentile > 0) { // resistant
sensResult = "Excess insulin resistance detected";
} else {
sensResult = "Sensitivity normal";
}
log.debug(sensResult);
double rawRatio = ratio;
ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7")));
ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2")));
if (ratio != rawRatio) {
ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio;
log.debug(ratioLimit);
}
log.error("Sensitivity to: " + new Date(toTime).toLocaleString() + " percentile: " + percentile);
AutosensResult output = new AutosensResult();
output.ratio = Round.roundTo(ratio, 0.01);
output.carbsAbsorbed = Round.roundTo(current.cob, 0.01);
output.pastSensitivity = pastSensitivity;
output.ratioLimit = ratioLimit;
output.sensResult = sensResult;
return output;
} }
public static JSONArray convertToJSONArray(IobTotal[] iobArray) { public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
JSONArray array = new JSONArray(); JSONArray array = new JSONArray();
for (int i = 0; i < iobArray.length; i++) { for (int i = 0; i < iobArray.length; i++) {

View file

@ -1,16 +1,34 @@
package info.nightscout.androidaps.plugins.SensitivityMK; package info.nightscout.androidaps.plugins.SensitivityMK;
import android.support.v4.util.LongSparseArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
/** /**
* Created by mike on 24.06.2017. * Created by mike on 24.06.2017.
*/ */
public class SensitivityMKPlugin implements PluginBase, SensitivityInterface{ public class SensitivityMKPlugin implements PluginBase, SensitivityInterface{
private static Logger log = LoggerFactory.getLogger(SensitivityMKPlugin.class);
private static boolean fragmentEnabled = true; private static boolean fragmentEnabled = true;
private static boolean fragmentVisible = false; private static boolean fragmentVisible = false;
@ -80,6 +98,103 @@ public class SensitivityMKPlugin implements PluginBase, SensitivityInterface{
@Override @Override
public AutosensResult detectSensitivity(long fromTime, long toTime) { public AutosensResult detectSensitivity(long fromTime, long toTime) {
return null; LongSparseArray<AutosensData> autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable();
String age = SP.getString(R.string.key_age, "");
int defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_adult))) defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) defaultHours = 4;
if (age.equals(MainApp.sResources.getString(R.string.key_child))) defaultHours = 4;
int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours);
long now = System.currentTimeMillis();
if (autosensDataTable == null || autosensDataTable.size() < 4) {
log.debug("No autosens data available");
return new AutosensResult();
}
AutosensData current = IobCobCalculatorPlugin.getAutosensData(toTime);
if (current == null) {
log.debug("No autosens data available");
return new AutosensResult();
}
List<Double> deviationsArray = new ArrayList<>();
String pastSensitivity = "";
int index = 0;
while (index < autosensDataTable.size()) {
AutosensData autosensData = autosensDataTable.valueAt(index);
if (autosensData.time < fromTime) {
index++;
continue;
}
if (autosensData.time > toTime) {
index++;
continue;
}
if (autosensData.time > now - hoursForDetection * 60 * 60 * 1000L)
deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d);
if (deviationsArray.size() > hoursForDetection * 60 / 5)
deviationsArray.remove(0);
pastSensitivity += autosensData.pastSensitivity;
int secondsFromMidnight = Profile.secondsFromMidnight(autosensData.time);
if (secondsFromMidnight % 3600 < 2.5 * 60 || secondsFromMidnight % 3600 > 57.5 * 60) {
pastSensitivity += "(" + Math.round(secondsFromMidnight / 3600d) + ")";
}
index++;
}
Double[] deviations = new Double[deviationsArray.size()];
deviations = deviationsArray.toArray(deviations);
Profile profile = MainApp.getConfigBuilder().getProfile();
double sens = profile.getIsf();
String ratioLimit = "";
String sensResult = "";
log.debug("Records: " + index + " " + pastSensitivity);
Arrays.sort(deviations);
double percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50);
double basalOff = percentile * (60 / 5) / Profile.toMgdl(sens, profile.getUnits());
double ratio = 1 + (basalOff / profile.getMaxDailyBasal());
if (percentile < 0) { // sensitive
sensResult = "Excess insulin sensitivity detected";
} else if (percentile > 0) { // resistant
sensResult = "Excess insulin resistance detected";
} else {
sensResult = "Sensitivity normal";
}
log.debug(sensResult);
double rawRatio = ratio;
ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7")));
ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2")));
if (ratio != rawRatio) {
ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio;
log.debug(ratioLimit);
}
log.error("Sensitivity to: " + new Date(toTime).toLocaleString() + " percentile: " + percentile);
AutosensResult output = new AutosensResult();
output.ratio = Round.roundTo(ratio, 0.01);
output.carbsAbsorbed = Round.roundTo(current.cob, 0.01);
output.pastSensitivity = pastSensitivity;
output.ratioLimit = ratioLimit;
output.sensResult = sensResult;
return output;
} }
} }

View file

@ -1,16 +1,33 @@
package info.nightscout.androidaps.plugins.SensitivityOref0; package info.nightscout.androidaps.plugins.SensitivityOref0;
import android.support.v4.util.LongSparseArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
/** /**
* Created by mike on 24.06.2017. * Created by mike on 24.06.2017.
*/ */
public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface{ public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface {
private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
private static boolean fragmentEnabled = true; private static boolean fragmentEnabled = true;
private static boolean fragmentVisible = false; private static boolean fragmentVisible = false;
@ -80,6 +97,114 @@ public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface{
@Override @Override
public AutosensResult detectSensitivity(long fromTime, long toTime) { public AutosensResult detectSensitivity(long fromTime, long toTime) {
return null; LongSparseArray<AutosensData> autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable();
String age = SP.getString(R.string.key_age, "");
int defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_adult))) defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) defaultHours = 24;
if (age.equals(MainApp.sResources.getString(R.string.key_child))) defaultHours = 24;
int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours);
long now = System.currentTimeMillis();
if (autosensDataTable == null || autosensDataTable.size() < 4) {
log.debug("No autosens data available");
return new AutosensResult();
}
AutosensData current = IobCobCalculatorPlugin.getLastAutosensData();
if (current == null) {
log.debug("No current autosens data available");
return new AutosensResult();
}
List<Double> deviationsArray = new ArrayList<>();
String pastSensitivity = "";
int index = 0;
while (index < autosensDataTable.size()) {
AutosensData autosensData = autosensDataTable.valueAt(index);
if (autosensData.time < fromTime) {
index++;
continue;
}
if (autosensData.time > toTime) {
index++;
continue;
}
if (autosensData.time > now - hoursForDetection * 60 * 60 * 1000L)
deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d);
if (deviationsArray.size() > hoursForDetection * 60 / 5)
deviationsArray.remove(0);
pastSensitivity += autosensData.pastSensitivity;
int secondsFromMidnight = Profile.secondsFromMidnight(autosensData.time);
if (secondsFromMidnight % 3600 < 2.5 * 60 || secondsFromMidnight % 3600 > 57.5 * 60) {
pastSensitivity += "(" + Math.round(secondsFromMidnight / 3600d) + ")";
}
index++;
}
Double[] deviations = new Double[deviationsArray.size()];
deviations = deviationsArray.toArray(deviations);
Profile profile = MainApp.getConfigBuilder().getProfile();
double sens = profile.getIsf();
double ratio = 1;
String ratioLimit = "";
String sensResult = "";
log.debug("Records: " + index + " " + pastSensitivity);
Arrays.sort(deviations);
for (double i = 0.9; i > 0.1; i = i - 0.02) {
if (IobCobCalculatorPlugin.percentile(deviations, (i + 0.02)) >= 0 && IobCobCalculatorPlugin.percentile(deviations, i) < 0) {
log.debug(Math.round(100 * i) + "% of non-meal deviations negative (target 45%-50%)");
}
}
double pSensitive = IobCobCalculatorPlugin.percentile(deviations, 0.50);
double pResistant = IobCobCalculatorPlugin.percentile(deviations, 0.45);
double basalOff = 0;
if (pSensitive < 0) { // sensitive
basalOff = pSensitive * (60 / 5) / Profile.toMgdl(sens, profile.getUnits());
sensResult = "Excess insulin sensitivity detected";
} else if (pResistant > 0) { // resistant
basalOff = pResistant * (60 / 5) / Profile.toMgdl(sens, profile.getUnits());
sensResult = "Excess insulin resistance detected";
} else {
sensResult = "Sensitivity normal";
}
log.debug(sensResult);
ratio = 1 + (basalOff / profile.getMaxDailyBasal());
double rawRatio = ratio;
ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7")));
ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2")));
if (ratio != rawRatio) {
ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio;
log.debug(ratioLimit);
}
double newisf = Math.round(Profile.toMgdl(sens, profile.getUnits()) / ratio);
if (ratio != 1) {
log.debug("ISF adjusted from " + Profile.toMgdl(sens, profile.getUnits()) + " to " + newisf);
}
AutosensResult output = new AutosensResult();
output.ratio = Round.roundTo(ratio, 0.01);
output.carbsAbsorbed = Round.roundTo(current.cob, 0.01);
output.pastSensitivity = pastSensitivity;
output.ratioLimit = ratioLimit;
output.sensResult = sensResult;
return output;
} }
} }