Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How is the calibration algorithm working? #87

Closed
TebbeUbben opened this issue Mar 21, 2017 · 4 comments
Closed

How is the calibration algorithm working? #87

TebbeUbben opened this issue Mar 21, 2017 · 4 comments

Comments

@TebbeUbben
Copy link
Contributor

Hello,

can anyone explain the mathematical process of the calibration algorithm to me?

@tzachi-dar
Copy link
Contributor

At a very high level, for each calibration there is a bg and raw value. We try to find the parameters of a straight line that will be as close as possible to this points.

In a little bit more details, each point gets a weight that is based on a few factors, such as how high it is, or how fast bg was changing.

@TebbeUbben
Copy link
Contributor Author

I would like to know exactly how a calibration is calculated. I'm pretty young, so I'm curious about such things. Would be pretty nice if you could answer my question :)

@tzachi-dar
Copy link
Contributor

Here is how slope and intercept are being calculated:
private static void calculate_w_l_s(boolean extended) {
if (Sensor.isActive()) {
double l = 0;
double m = 0;
double n = 0;
double p = 0;
double q = 0;
double w;

        final SlopeParameters sParams = getSlopeParameters();

        List<Calibration> calibrations = allForSensorInLastFourDays(); //5 days was a bit much, dropped this to 4

        if (calibrations == null) {
            Log.e(TAG, "Somehow ended up with null calibration list!");
            Home.toaststatic("Somehow ended up with null calibration list!");
            return;
        }

        // less than 5 calibrations in last 4 days? cast the net wider if in extended mode
        final int ccount = calibrations.size();
        if ((ccount < 5) && extended) {
            calibrations = allForSensorLimited(5);
            if (calibrations.size() > ccount) {
                Home.toaststaticnext("Calibrated using data beyond last 4 days");
            }
        }

        if (calibrations.size() <= 1) {
            Calibration calibration = Calibration.last();
            calibration.slope = 1;
            calibration.intercept = calibration.bg - (calibration.raw_value * calibration.slope);
            calibration.save();
            CalibrationRequest.createOffset(calibration.bg, 25);
            newFingerStickData();
        } else {
            for (Calibration calibration : calibrations) {
                w = calibration.calculateWeight();
                l += (w);
                m += (w * calibration.estimate_raw_at_time_of_calibration);
                n += (w * calibration.estimate_raw_at_time_of_calibration * calibration.estimate_raw_at_time_of_calibration);
                p += (w * calibration.bg);
                q += (w * calibration.estimate_raw_at_time_of_calibration * calibration.bg);
            }

            Calibration last_calibration = Calibration.last();
            w = (last_calibration.calculateWeight() * (calibrations.size() * 0.14));
            l += (w);
            m += (w * last_calibration.estimate_raw_at_time_of_calibration);
            n += (w * last_calibration.estimate_raw_at_time_of_calibration * last_calibration.estimate_raw_at_time_of_calibration);
            p += (w * last_calibration.bg);
            q += (w * last_calibration.estimate_raw_at_time_of_calibration * last_calibration.bg);

            double d = (l * n) - (m * m);
            Calibration calibration = Calibration.last();
            calibration.intercept = ((n * p) - (m * q)) / d;
            calibration.slope = ((l * q) - (m * p)) / d;
            if ((calibrations.size() == 2 && calibration.slope < sParams.getLowSlope1()) || (calibration.slope < sParams.getLowSlope2())) { // I have not seen a case where a value below 7.5 proved to be accurate but we should keep an eye on this
                calibration.slope = calibration.slopeOOBHandler(0);
                if (calibrations.size() > 2) {
                    calibration.possible_bad = true;
                }
                calibration.intercept = calibration.bg - (calibration.estimate_raw_at_time_of_calibration * calibration.slope);
                CalibrationRequest.createOffset(calibration.bg, 25);
            }
            if ((calibrations.size() == 2 && calibration.slope > sParams.getHighSlope1()) || (calibration.slope > sParams.getHighSlope2())) {
                calibration.slope = calibration.slopeOOBHandler(1);
                if (calibrations.size() > 2) {
                    calibration.possible_bad = true;
                }
                calibration.intercept = calibration.bg - (calibration.estimate_raw_at_time_of_calibration * calibration.slope);
                CalibrationRequest.createOffset(calibration.bg, 25);
            }
            Log.d(TAG, "Calculated Calibration Slope: " + calibration.slope);
            Log.d(TAG, "Calculated Calibration intercept: " + calibration.intercept);

            if ((calibration.slope == 0) && (calibration.intercept == 0)) {
                calibration.sensor_confidence = 0;
                calibration.slope_confidence = 0;
                Home.toaststaticnext("Got invalid zero slope calibration!");
                calibration.save(); // Save nulled record, lastValid should protect from bad calibrations
                newFingerStickData();

            } else {
                calibration.save();
                newFingerStickData();
            }
        }
    } else {
        Log.d(TAG, "NO Current active sensor found!!");
    }
}

you can see more in the file:
https://github.com/NightscoutFoundation/xDrip/blob/master/app/src/main/java/com/eveningoutpost/dexdrip/Models/Calibration.java

@TebbeUbben
Copy link
Contributor Author

Okay, and what's the meaning and purpose of the variables you mentioned above?

jamorham added a commit that referenced this issue Jun 27, 2019
Add try/catch block around delta calculation for JSON upload
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants