copy old oref0 sensitivity code
This commit is contained in:
parent
b39f59f59e
commit
70aaafa616
|
@ -215,6 +215,10 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
|
|||
return activePump;
|
||||
}
|
||||
|
||||
public static SensitivityInterface getActiveSensitivity() {
|
||||
return activeSensitivity;
|
||||
}
|
||||
|
||||
void logPluginStatus() {
|
||||
for (PluginBase p : pluginList) {
|
||||
log.debug(p.getName() + ":" +
|
||||
|
|
|
@ -7,11 +7,11 @@ import java.util.Date;
|
|||
*/
|
||||
|
||||
public class AutosensData {
|
||||
long time = 0L;
|
||||
public long time = 0L;
|
||||
public String pastSensitivity = "";
|
||||
public double deviation = 0d;
|
||||
boolean nonCarbsDeviation = false;
|
||||
boolean nonEqualDeviation = false;
|
||||
public boolean nonEqualDeviation = false;
|
||||
double absorbed = 0d;
|
||||
public double carbsFromBolus = 0d;
|
||||
public double cob = 0;
|
||||
|
|
|
@ -29,6 +29,7 @@ import info.nightscout.androidaps.events.EventNewBG;
|
|||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
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.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||
|
@ -55,9 +56,9 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
private static Handler sHandler = 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() {
|
||||
if (plugin == null)
|
||||
|
@ -65,6 +66,14 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
public static LongSparseArray<AutosensData> getAutosensDataTable() {
|
||||
return autosensDataTable;
|
||||
}
|
||||
|
||||
public static List<BgReading> getBucketedData() {
|
||||
return bucketed_data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return GENERAL;
|
||||
|
@ -120,7 +129,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
|
||||
}
|
||||
|
||||
public IobCobCalculatorPlugin() {
|
||||
IobCobCalculatorPlugin() {
|
||||
MainApp.bus().register(this);
|
||||
if (sHandlerThread == null) {
|
||||
sHandlerThread = new HandlerThread(IobCobCalculatorPlugin.class.getSimpleName());
|
||||
|
@ -198,14 +207,14 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
public void createBucketedData() {
|
||||
private void createBucketedData() {
|
||||
if (isAbout5minData())
|
||||
createBucketedData5min();
|
||||
else
|
||||
createBucketedDataRecalculated();
|
||||
}
|
||||
|
||||
public void createBucketedDataRecalculated() {
|
||||
private void createBucketedDataRecalculated() {
|
||||
synchronized (dataLock) {
|
||||
if (bgReadings == null || bgReadings.size() < 3) {
|
||||
bucketed_data = null;
|
||||
|
@ -310,7 +319,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
//log.debug("Releasing createBucketedData");
|
||||
}
|
||||
|
||||
public void calculateSensitivityData() {
|
||||
private void calculateSensitivityData() {
|
||||
if (MainApp.getConfigBuilder() == null)
|
||||
return; // app still initializing
|
||||
//log.debug("Locking calculateSensitivityData");
|
||||
|
@ -523,106 +532,10 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
public static AutosensResult detectSensitivity(long fromTime, long toTime) {
|
||||
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 = 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;
|
||||
private static AutosensResult detectSensitivity(long fromTime, long toTime) {
|
||||
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
|
||||
}
|
||||
|
||||
|
||||
public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (int i = 0; i < iobArray.length; i++) {
|
||||
|
|
|
@ -1,16 +1,34 @@
|
|||
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.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
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.IobCobCalculatorPlugin;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.06.2017.
|
||||
*/
|
||||
|
||||
public class SensitivityMKPlugin implements PluginBase, SensitivityInterface{
|
||||
private static Logger log = LoggerFactory.getLogger(SensitivityMKPlugin.class);
|
||||
|
||||
private static boolean fragmentEnabled = true;
|
||||
private static boolean fragmentVisible = false;
|
||||
|
||||
|
@ -80,6 +98,103 @@ public class SensitivityMKPlugin implements PluginBase, SensitivityInterface{
|
|||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,33 @@
|
|||
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.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
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.IobCobCalculatorPlugin;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
/**
|
||||
* 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 fragmentVisible = false;
|
||||
|
||||
|
@ -80,6 +97,114 @@ public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface{
|
|||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue