weightedaverage sensitivity
This commit is contained in:
parent
31e9f3f55c
commit
8de7e05dd5
|
@ -50,6 +50,7 @@ import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
|||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorFragment;
|
||||
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gPlugin;
|
||||
|
@ -101,6 +102,7 @@ public class MainApp extends Application {
|
|||
pluginsList.add(InsulinFastactingProlongedFragment.getPlugin());
|
||||
pluginsList.add(SensitivityOref0Plugin.getPlugin());
|
||||
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
|
||||
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
|
||||
if (Config.DANAR) pluginsList.add(DanaRFragment.getPlugin());
|
||||
if (Config.DANAR) pluginsList.add(DanaRKoreanFragment.getPlugin());
|
||||
if (Config.DANARv2) pluginsList.add(DanaRv2Fragment.getPlugin());
|
||||
|
|
|
@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
|||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||
import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
|
||||
import info.nightscout.utils.LocaleHelper;
|
||||
|
@ -95,8 +96,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
super.onCreate(savedInstanceState);
|
||||
if (Config.ALLPREFERENCES) {
|
||||
addPreferencesFromResource(R.xml.pref_password);
|
||||
addPreferencesFromResource(R.xml.pref_age);
|
||||
}
|
||||
addPreferencesFromResource(R.xml.pref_age);
|
||||
addPreferencesFromResource(R.xml.pref_language);
|
||||
if (Config.ALLPREFERENCES) {
|
||||
addPreferencesFromResource(R.xml.pref_quickwizard);
|
||||
|
@ -112,7 +113,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
if (MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class) != null && MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class).isEnabled(PluginBase.APS))
|
||||
addPreferencesFromResource(R.xml.pref_openapsama);
|
||||
}
|
||||
if (MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class) != null && MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class).isEnabled(PluginBase.SENSITIVITY))
|
||||
if (MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class) != null && MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class).isEnabled(PluginBase.SENSITIVITY)
|
||||
|| MainApp.getSpecificPlugin(SensitivityWeightedAveragePlugin.class) != null && MainApp.getSpecificPlugin(SensitivityWeightedAveragePlugin.class).isEnabled(PluginBase.SENSITIVITY))
|
||||
addPreferencesFromResource(R.xml.pref_absorption_aaps);
|
||||
if (MainApp.getSpecificPlugin(SensitivityOref0Plugin.class) != null && MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).isEnabled(PluginBase.SENSITIVITY))
|
||||
addPreferencesFromResource(R.xml.pref_absorption_oref0);
|
||||
|
|
|
@ -215,6 +215,30 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
createBucketedDataRecalculated();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BgReading findNewer(long time) {
|
||||
BgReading lastFound = bgReadings.get(0);
|
||||
if (lastFound.date < time) return null;
|
||||
for (int i = 1; i < bgReadings.size(); ++i) {
|
||||
if (bgReadings.get(i).date > time) continue;
|
||||
lastFound = bgReadings.get(i);
|
||||
if (bgReadings.get(i).date < time) break;
|
||||
}
|
||||
return lastFound;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BgReading findOlder(long time) {
|
||||
BgReading lastFound = bgReadings.get(bgReadings.size() - 1);
|
||||
if (lastFound.date > time) return null;
|
||||
for (int i = bgReadings.size() - 2; i >=0 ; --i) {
|
||||
if (bgReadings.get(i).date < time) continue;
|
||||
lastFound = bgReadings.get(i);
|
||||
if (bgReadings.get(i).date > time) break;
|
||||
}
|
||||
return lastFound;
|
||||
}
|
||||
|
||||
private void createBucketedDataRecalculated() {
|
||||
synchronized (dataLock) {
|
||||
if (bgReadings == null || bgReadings.size() < 3) {
|
||||
|
@ -224,29 +248,24 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
|
||||
bucketed_data = new ArrayList<>();
|
||||
long currentTime = bgReadings.get(0).date + 5 * 60 * 1000 - bgReadings.get(0).date % (5 * 60 * 1000) - 5 * 60 * 1000L;
|
||||
log.debug("First reading: " + new Date(bgReadings.get(0).date).toLocaleString() + " Staring at: " + new Date(currentTime).toLocaleString());
|
||||
double newerbg = bgReadings.get(0).value;
|
||||
long newerbgTime = bgReadings.get(0).date;
|
||||
for (int i = 1; i < bgReadings.size(); ++i) {
|
||||
//log.debug("First reading: " + new Date(currentTime).toLocaleString());
|
||||
|
||||
while (true) {
|
||||
// test if current value is older than current time
|
||||
double olderbg = bgReadings.get(i).value;
|
||||
long olderTime = bgReadings.get(i).date;
|
||||
if (olderTime > currentTime) {
|
||||
newerbg = olderbg;
|
||||
newerbgTime = olderTime;
|
||||
continue;
|
||||
}
|
||||
BgReading newer = findNewer(currentTime);
|
||||
BgReading older = findOlder(currentTime);
|
||||
if (newer == null || older == null)
|
||||
break;
|
||||
|
||||
double bgDelta = newerbg - olderbg;
|
||||
long timeDiffToNew = newerbgTime - currentTime;
|
||||
double bgDelta = newer.value - older.value;
|
||||
long timeDiffToNew = newer.date - currentTime;
|
||||
|
||||
double currentBg = newerbg - (double) timeDiffToNew / (newerbgTime - olderTime) * bgDelta;
|
||||
double currentBg = newer.value - (double) timeDiffToNew / (newer.date - older.date) * bgDelta;
|
||||
BgReading newBgreading = new BgReading();
|
||||
newBgreading.date = currentTime;
|
||||
newBgreading.value = Math.round(currentBg);
|
||||
bucketed_data.add(newBgreading);
|
||||
newerbg = olderbg;
|
||||
newerbgTime = olderTime;
|
||||
//log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")");
|
||||
currentTime -= 5 * 60 * 1000L;
|
||||
|
||||
}
|
||||
|
@ -645,6 +664,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
log.debug("Invalidating cached data to: " + new Date(time).toLocaleString());
|
||||
for (int index = iobTable.size() - 1; index >= 0; index--) {
|
||||
if (iobTable.keyAt(index) > time) {
|
||||
if (Config.logAutosensData)
|
||||
if (Config.logAutosensData)
|
||||
log.debug("Removing from iobTable: " + new Date(iobTable.keyAt(index)).toLocaleString());
|
||||
iobTable.removeAt(index);
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
package info.nightscout.androidaps.plugins.SensitivityWeightedAverage;
|
||||
|
||||
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 SensitivityWeightedAveragePlugin implements PluginBase, SensitivityInterface{
|
||||
private static Logger log = LoggerFactory.getLogger(SensitivityWeightedAveragePlugin.class);
|
||||
|
||||
private static boolean fragmentEnabled = true;
|
||||
private static boolean fragmentVisible = false;
|
||||
|
||||
static SensitivityWeightedAveragePlugin plugin = null;
|
||||
|
||||
public static SensitivityWeightedAveragePlugin getPlugin() {
|
||||
if (plugin == null)
|
||||
plugin = new SensitivityWeightedAveragePlugin();
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return SENSITIVITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainApp.sResources.getString(R.string.sensitivityweightedaverage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
return MainApp.sResources.getString(R.string.sensitivity_shortname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
return type == SENSITIVITY && fragmentEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
return type == SENSITIVITY && fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == SENSITIVITY) this.fragmentVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AutosensResult detectSensitivity(long fromTime, long toTime) {
|
||||
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);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
String pastSensitivity = "";
|
||||
int index = 0;
|
||||
LongSparseArray<Double> data = new LongSparseArray<>();
|
||||
|
||||
while (index < autosensDataTable.size()) {
|
||||
AutosensData autosensData = autosensDataTable.valueAt(index);
|
||||
|
||||
if (autosensData.time < fromTime) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (autosensData.time > toTime) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (autosensData.time < toTime - hoursForDetection * 60 * 60 * 1000L) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//data.append(autosensData.time);
|
||||
long reverseWeight = (toTime - autosensData.time) / (5 * 60 * 1000L);
|
||||
data.append(reverseWeight, autosensData.nonEqualDeviation ? autosensData.deviation : 0d);
|
||||
//weights += reverseWeight;
|
||||
//weightedsum += reverseWeight * (autosensData.nonEqualDeviation ? autosensData.deviation : 0d);
|
||||
|
||||
|
||||
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 weightedsum = 0;
|
||||
double weights = 0;
|
||||
|
||||
long hightestWeight = data.keyAt(data.size() - 1);
|
||||
for (int i = 0 ; i < data.size(); i++) {
|
||||
long reversedWeigth = data.keyAt(i);
|
||||
double value = data.valueAt(i);
|
||||
double weight = (hightestWeight - reversedWeigth) / 2;
|
||||
weights += weight;
|
||||
weightedsum += weight * value;
|
||||
}
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
|
||||
double sens = profile.getIsf();
|
||||
|
||||
String ratioLimit = "";
|
||||
String sensResult = "";
|
||||
|
||||
log.debug("Records: " + index + " " + pastSensitivity);
|
||||
|
||||
double average = weightedsum /weights;
|
||||
double basalOff = average * (60 / 5) / Profile.toMgdl(sens, profile.getUnits());
|
||||
double ratio = 1 + (basalOff / profile.getMaxDailyBasal());
|
||||
|
||||
if (average < 0) { // sensitive
|
||||
sensResult = "Excess insulin sensitivity detected";
|
||||
} else if (average > 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.debug("Sensitivity to: " + new Date(toTime).toLocaleString() + " weightedaverage: " + average + " ratio: " + ratio);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -677,4 +677,5 @@
|
|||
<string name="lock_screen">Lock screen</string>
|
||||
<string name="lock_screen_short">Lock</string>
|
||||
<string name="sensitivity_warning">By turning on Autosense feature remember to enter all eated carbs. Otherwise carbs deviations will be identified wrong as sensitivity change !!</string>
|
||||
<string name="sensitivityweightedaverage">Sensitivity WeightedAverage</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue