Skip to content

Latest commit

 

History

History
61 lines (33 loc) · 14.5 KB

File metadata and controls

61 lines (33 loc) · 14.5 KB

Glucose Prediction

All of Loop's insulin dosing decisions are based on the difference between the target glucose and Loop's glucose prediction. Therefore, the best way to understand Loop's recommendations is to understand the prediction. There are four factors that determine Loop's prediction: insulin activity, carbohydrate activity, glucose momentum and, optionally, retrospective correction.

You can see the individual contributions of these effects by tapping on the predicted glucose graph on Loop's status screen. In addition, by tapping on the Active Carbohydrates screen, you can see important information about carbohydrate absorption and its effect on the glucose prediction.

You may find it helpful to view this slideshow before or after reading the rest of this section.

Loop makes a new prediction every five minutes and each time it does so, it generates a vector of expected changes to the glucose value for each of the four effects, for each point in the future. Loop then combines these effects together to generate a predicted glucose curve. The curve ends at the "eventual" glucose prediction time. This time is at the end of the Duration of Insulin Action - the DIA, which you have supplied in the settings screen.

It makes sense to anchor the dosing recommendations on the prediction at the end of the DIA because that's when all the insulin is expected to be absorbed. If the prediction were longer than the DIA, there would no action to be taken now to treat the predicted trend after the DIA; we need to wait for those effects to come inside the DIA. And treating based on a prediction that is shorter than the DIA risks ignoring IOB after the prediction horizon, which could produce hypoglycemia.

Since all dosing decisions are based on the eventual prediction, you might wonder why the path of the prediction matters. Why not just generate a single number, the eventual prediction, and focus on that? While the answer to this question may seem obvious, it's useful to lay out the specific reasons:

  • As you can see in the following section, Loop checks to make sure that at no point will your BG go below the Minimum BG guard. To do this, Loop needs the full curve.

  • Since the whole point of Loop is to continually make small adjustments to temp basals in response to the latest prediction, Loop needs to have a model for how insulin and carbs are expected to decay after meals and boluses, as well as after temp basal adjustments. Since the work has to be done anyway to keep track of all the carb and insulin events, and decay each one as time passes, the full curve is relatively easy to produce.

  • Having a prediction for every point in time allows Loop to frequently compare predictions to actual BG. This difference is the key input to Restrospective Correction.

  • The insulin activity component of the curve after meals, during carb absorption, is necessary to implement dynamic carbs, a key recent enhancement.

  • The complete curve can be leveraged for more sophisticated algorithms being considered, including supporting faster acting insulin and adding the ability to be more aggressive with treatment decisions if you want.

Insulin absorption curves: Loop needs a model for how insulin is absorbed by your body to determine its expected effect on BG at every point in the future after a bolus or a temp basal adjustment. You are probably used to thinking about the peak and the tail of your boluses in order to avoid late lows and decide pre-bolusing, but the Loop prediction can do the math much more precisely and give you an estimate for what impact insulin is expected to have on your BG in every 5 minute interval between now and when all the insulin is gone. And, it can do this across multiple boluses and temp basals, which can help to explain why sometimes BG is moving in a way that seems inconsistent with the IOB, due to different insulin absorption rates across potentially offsetting boluses and temp basals. This, together with incorporating the impact on IOB of temp basals, is a significant benefit of the way Loop handles insulin decay compared to just having to rely on the IOB reported by the pump.

In the current version of Loop, insulin is assumed to absorb according to curves first published by Walsh. These curves are then squeezed or stretched by the DIA that you input. The results are illustrated in the tables below:

WalshExcelTables

The curves in question are fourth order polynomials in the form Walsh, with t supplied in minutes. Loop has three sets of coefficients for curves with DIA equal to 3, 4 and 5:

WalshPolyCoeff

Loop then takes your inputted DIA, rounds it, and picks which curve is going to be used based on which of the three curves is closest to your rounded DIA. Then, it shrinks or stretches the "benchmark" curve to match the DIA you have inputted. For example, if you input DIA of 3.6, it will round to 4, and pick the curve with DIA = 4. Then, it will "shrink" that curve so that instead of ending after 4 hours, it ends after 3 hours and 36 minutes (3.6 hours), and the times for all the IOBs in between are similarly scaled, as shown in this example:

DIA_squeeze_example

The choice of the fourth order polynomial is just a mathematical convenience that the developers of GlucoDyn used to fit the Walsh curves. The coefficients in the polynomial don't "mean" anything - they don't, for example, relate to peak time or to DIA explicitly. (The one exception to this is the intercept "e", which represents the fraction of the IOB that is present at time = 0. Given that, it should be 1 in all cases, but for whatever reason that's not the case. The difference is insignificant).

The Loop community is currently exploring updating these mathematical functions to be more flexible, accurate and intuitive. Among other things, alternate forms of these functions would allow Loop users to more accurately reflect the earlier peak of faster acting insulins like Fiasp, while still recognizing that a tail exists. If you are considering using faster acting insulin and you want to know how to adjust the DIA, you should become familiar with issue #533. Simply shortening the DIA of the existing curve shape to match the earlier peak of a faster acting insulin like Fiasp risks ignoring significant amounts of insulin in the tail which could produce unwanted lows. There is an extensive discussion of these issues in #388, but it is not necessary to understand the math in these discussions to use Loop succesfully!

Carbohydrate absorption: Version 1.4.0 implements dynamic carbohydrate absorption, which is a major step forward for Loop. The write-up associated with the original release of dynamic carbs is here, and that is the best place to get a full understanding. From the perspective of the glucose prediction, the most important aspect of dynamic carbs is that carbohydrates on board (COB) are equal to the carbs you entered minus observed carbs absorbed. Carbs absorbed are derived by looking at the BG history. Since Loop knows the expected effect on BG of all insulin taken, it can assume that immediately after meals, any difference between the predicted BG from insulin alone and the observed BG is due to the absorption of carbs. This is a change from prior versions where COB was decayed according to a mathematical function, without reference to observed absorption. This could mean that if BG went up very quickly after a eating, the prediction would also go up, leading to high temping, which would turn out to be unnecessary - because the increase in BG simply represented accelerated absorption of carbs which affected the path of the BG, but not the eventual glucose prediction. If this unnecessary high temping was significant enough, you could run out of time and basal "cushion" to offset with low temping, and wind up with a low.

With dynamic carb absorption, as time passes, the COB is decreased by the observed absorption of the carbs. This means that as time passes the number of carbs whose decay is being modeled mathematically is decreasing, which makes the modeling choice increasingly less significant over time. As a result, as part of the implementation of dynamic carbs, the mathematical modeling of carb decay in Loop has been significantly simplified. Now, unabsorbed carbs are simply assumed to decay linearly, at a rate equal to (inputted carbs/inputted absorption time)/1.5.

The carbohydrate detail screen allows you to see the exact amount and absorption profile of observed carbs. Checking this screen can help with carb counting, and also give you a sense of whether there are other factors at play - exercise, basal rates needing to be modified, stress, etc. The screen also allows you to see what actual absorption times have been.

Observing the carb absorption screen may lead you to call into question the factor of 1.5, which is designed to allow more aggressive management of slow burning meals with many carbs outside the DIA while still protecting against lows; but it's important to realize that this factor makes very little difference for meals expected to absorb well inside the DIA. For example if you have a DIA of 4, and you input an absorption time of 2 hours, Loop is actually using 3 hours - but that still means it believes all carbs will be absorbed inside the DIA, so it recommends a full bolus for the carbs that you are consuming. On the other hand, if you input a 4 hour absorption with a DIA of 4, and your estimate of the absorption time turns out to be exactly right, you may feel that the algorithm is a bit conservative - because in this case Loop will only bolus for 4/6 of the carbs, since it's extending your absorption time estimate from 4 to 6 hours, and will then be high-temping for the remaining 1/3 of the carbs as they start to come inside the DIA. And, if you are aggressively pre-bolusing, it's possible that the 50% buffer will produce a BG guard alert that won't actually happen, because the carbs are absorbing faster than Loop's minimum absorption assumption and so the actual glucose path won't cross the minumum BG guard. You can offset this effect by either inputting faster absorption times than you believe, or by changing the code according to these instructions. Whether you choose to make these adjustments is a function of your willingness to risk lows and your confidence in your ability to estimate absorption times, and should probably only be considered after some experience with the unmodified algorithm.

Retrospective correction: this feature adjusts the prediction by the previously observed error in the prediction, and thereby serves as a catch-all for "all other effects" - exercise, stress, hormones, etc. RC takes the current BG and compares it to what it was predicted to be half an hour ago. It then implies a "drift rate" between the prediction and the actual BG by dividing the difference by the time over which it developed, half an hour. Loop then incorporates that drift rate into the prediction for the next 60 minutes, decaying it to zero at the end of the 60 minutes. So if the prediction was too low by 10mg/dl, that implies a drift rate of 2 mg/dl/5minutes over the prior 30 minutes. The next five minutes then have 2*(11/12) added to the prediction, and the last five minutes have 2*(1/12) added to the prediction. In most cases this is adequately simplified by taking half the drift rate and adding it to each 5 minute interval for the next 60 minutes. As a further simplification, since the main driver of treatment recommendations is the eventual BG, that impact is well approximated by taking the absolute RC and adding it to the eventual glucose prediction - because a change observed over 30 minutes is applied over an hour, but decayed down to zero in that period. So in our example, the eventual BG prediction would be increased by approximately 10 mg/dl.

Glucose momentum: In essence, glucose momentum says that what has been happening over the last 15 minutes is the best predictor of what will happen over the next 5 minutes, but it's not relevant to anything happening after half an hour from now, with points in the middle decayed linearly. So, the prediction 5 minutes from now is almostly completely based on momentum. The prediction 25 minutes from now is 1/6th momentum and 5/6th other effects (insulin, carb and RC). In effect the impact of momentum is "blended" with the other effects and stops contributing half an hour into the forecast. Mathematically, Loop takes the regression slope coefficient of the last 4 glucose measurements (one every 5 minutes, so looking back 15 minutes including the current measurement) to get the recent trend. This is pretty close to taking the average of the last 3 changes. (You can see the changes in mg/dl/5 minutes in Nightscout - this is also the value that drives the trend arrows in Loop and the CGM). Then, Loop looks forward to the next half hour and "blends" the calculated trend with the other effects. In the special case of no COB, IOB, and no RC, glucose momentum approximates to taking the average change of the last 15 minutes, dividing it in half, and using it to project forward for the next half hour. But, if there are any COB or IOB effects, those will "take over" the momentum effect as time pases, and this approximation won't apply.

Bringing it all together with a worked example: This slideshow will take you through the prediction components step by step.