Why DIA matters

DIA: Duration of Insulin Action

At our first endocrinologist appointment, I distinctly remember the doctor telling us that rapid acting insulins (like humalog and novolog) had insulin durations of about 5 hours.  I remember looking at the insulin curves…and I remember that the curves were distinctly skewed to the left.  Meaning, most of the insulin “action” seemed to be in the first few hours and it peaked around 90 minutes.  I also remember them saying to wait until about 2 hours had passed since the last insulin dose before considering a corrective dose of insulin…to give that insulin its due time to work.  Based on that information, I had concluded that the “tail” of the insulin duration (from hours 3-5) contributed relatively little to the insulin experience.  After all, looking at curves like the one below, it would pretty easy to say that the effect of insulin seems pretty darned small between hours 3-5 compared to hours 0-3.


Back when we were on omnipod, we used a 2 hour DIA.  Basically, we picked that setting because it seemed like after about 2 hours we noticed that insulin seemed to wear off…corrections from high BGs slowed way down after 2 hours, or our BG control of food seemed to falter for big meals around 2 hours and we’d need to give more.  We had pretty great control with 2 hours of DIA.

Our omnipod system basically only used the DIA to calculate the insulin remaining after it had been given…the insulin-on-board (IOB).  So, if BGs were coming down too quickly (have you seen what happens to kids’ BGs on trampolines?), we would look at the IOB and eat an appropriate amount of carbs to try to offset the remaining IOB.

I always knew my estimate of DIA was probably a little off.  I knew I was ignoring that little bit of insulin effect from hours 3-5.  Especially because when we had large carb meals…the system would tell me that her insulin had gone to zero, but Anna would still be dropping.  On large carb meals, those “little bits of tail” between hours 3-5 added up to a significant amount because our boluses were proportionately bigger.  The “noise” of everyday diabetes variations were less apt to hide the 3-5 hour insulin on those big meals.  But most of the time 2 hours seemed to work “about right”…so we stuck to it.

Since we’ve started to manage diabetes with closed loop systems (OpenAPS and Loop), the effect of DIA (and especially that late insulin effect tail) has become more apparent and important.  So, I thought it would be good to discuss just how DIA can impact closed loop operations.

I like to visualize carbs and insulin as opposite effects on BGs; one upward and one downward.  I have several visuals that I typically imagine…my favorite two are crowd surfers at concerts and wet paper towels holding coins.

Imagine carbs are the hands below.  Imagine insulin is the weight of the crowd surfer.  If you had a bunch of weak little kids trying to hold up The Rock (an all fat/protein meal bolused upfront entirely)…BGs would get crushed low.  If you had a tiny little baby being held up by rambunctious steroid-filled weight lifters (underbolused slurpee)…that BG might go sailing high.


Or how about the wet paper towel is a meal and the coins are insulin dosing. Can you put too many coins suddenly on that wet paper towel such that it can’t support the weight of the coins?  Yup…low BG.  Give that towel time to dry out, get strong (carbs absorb)…then it would be able to support those coins later.


With those comparisons in mind, we can look at the geeky explanation a bit more.  Simply put, carbs make your BGs go up.  Loop used to predict the “shape” that carbs would absorb as a static value much like shown below.  You’d tell Loop the time for carb absorption, and the model said it would peak halfway through….BG impacts would look much like my hand-drawn sketch below.  (Please keep in mind these are conceptual drawings…not to any scale exactly.)

dia 1

And insulin makes your BGs go down…

dia 2

If you add the up and down effects together…you hope to get a fairly even final BG curve.  We’re all aware of the difficulty in lining all of this up to achieve that…some foods absorb faster than insulin kicks in (so we try to prebolus to help that), some foods absorb so slow that insulin wears off before the food is done (so we do extended boluses to help that).  If the stars aligned, you may get a fairly good match between the downs and ups…to get a fairly flat BG result.

dia 3

If we take a closer look at those downward forces, the insulin effect, we can conceptualize that as an “area under the curve”.  All that drawing is a bunch of little tiny insulin effects added up together.  If that was one unit of insulin with an ISF= 30 and a DIA of 4 hours…you’d expect your BG to drop 30mg/dl over the entire 4 hours (assuming your basals are correct).

dia 4

But, what would happen if you considered DIA of 2 hours?  Like I’d been doing with my omnipod?  Well, all that insulin action (aka “area under the curve”) still needs to be there, so the shape of the curve changes as a result.  Like moving play-doh into a new shape.  Since the length is cut in half, the height of that curve will necessarily get longer.  The curve become more pointy, less like a upside-down bell and more like an upside-down mountain.

dia 5

In effect, BGs will still drop 30 mg/dl in both situations based on the “math” but the BGs will drop MUCH faster and stronger with the shorter DIA.

dia 6

The shape of the curves didn’t make much of a difference to us when we were using omnipod because we typically only were using the omnipod’s DIA setting much later after the bolus had been given…way down near the post-2 hours, post-3 hours after a bolus had been given when the two different curves might start to look more similar again.  We were checking IOB at times well after a meal had been bolused.

Additionally, we weren’t using DIA to calculate boluses ahead of time…all the boluses were based strictly off carb ratios and MY ABILITY to guess whether Anna would go low if I gave all the carb ratio based bolus upfront.    Quick carbs…I gave all the insulin up front.  Slow carbs…ummm, let me think about how much to give now and how much to extend and for how long.  Anyone have a calculator?  My omnipod PDM never suggested  proactively “Hey Katie, if Anna is eating pizza, you may want to give that 10 units broken up as 6 units now and 4 units extended over the next 2 hours or else she’ll be low in an hour.”  Wouldn’t that have been nice?! (hint: that’s what Loop is able to do now!!!)

So why is DIA different with Loop?  Well, it matters a whole bunch now because Loop is calculating what your curve will look like as soon as you enter carbs and a carb absorption time before you bolus.  If your upward effects (carbs) are not able to keep up with the downward effects (insulin), Loop is going worry about you going below your target BG.  It wants you safe.  If you have a short DIA, the chances increase that your Loop will think that the insulin will overpower the carbs early in a meal and you’ll have a low sag in BGs before carbs can catch up. (because hey…all that orange “area under the curve” has been crunched up into the front part!)

dia 7

So, when Loop does its number crunching and sees that low BG sag…Loop’s checking whether that low is “low enough” to take you below your target BG.  If that low is low enough, Loop will shave off some of your recommended bolus upfront from meal.  How much?  JUST ENOUGH to keep your predicted BG from going below your target anytime after you bolus.

dia 8

If you’re starting the meal near your target BG, you’re likely to see a prediction line something like the graph below after you use the recommended bolus from Loop.  And you will scratch your head and say “WHAT THE HECK IS GOING ON?”  Why would Loop SHOW that you’re going to be going high just after giving a meal bolus and not suggest more?  (some people may even take matters into their own hands and say “hey, it shorted me on a bolus…it should’ve been offering 6 units and only  recommended 4 units!”  And you’ll shortly find that if you manually change it to deliver 6 units, you’ll find Loop suspending you quickly afterwards)

BUT, take a pause and think about the situation.  What you aren’t seeing is that Loop is offering that amount of bolus to keep you from going low early…before carbs can catch up.  Based on the meal specs (carbs and carb absorption time) you entered and the DIA you are using, Loop is helping you know that an extended bolus is a good idea!  Don’t worry, Loop still knows about the upward carbs…it hasn’t forgotten about them at all.  In fact, it is literally SHOWING you that it has not forgotten about those carbs that still need insulin.  Loop will make up the remaining bolus needed through high temp basals as soon as the predicted BGs aren’t showing you’ll go below target.

dia 9

Isn’t that awesome?!  In the pre-Loop days, you’d have to recognize the meal needed an extended/dual wave bolus, do some guessing and memory games, watch the CGM to help decide when it was safe to give more insulin.  Now with Loop, you tell it “hey this is a kind of long slow meal” and it does the work of helping you extend the bolus.

The problem comes if you are using too short of a DIA…you’ll regularly get boluses that are lower than you’d expect (or likely want) because Loop is predicting a significant downward insulin effect early in the meal.  Going back to the simple models, you are telling Loop that you have a wet paper towel (slow carb meal with weak upward support) but want to drop a huge stack of coins immediately.  Loop is telling you to “hey, don’t drop an huge stack of coins on that wet paper towel right away…drop a few coins, wait for the towel to dry out a bit and you’ll be able to add more later safely.”

All of this was to demonstrate the not-so-trivial weight that DIA has in your Looping.  If you set that DIA too short, you’re not just going to see it in IOB calculations, you’re also going to be having boluses and predicted BG curves that aren’t realistic.  Looping in those situations will be less than optimal and you’ll likely feel frustrated.  Out of all the variables that are YDMV (your diabetes may vary) such as basal rates, ISF, and carb ratios…DIA is the LEAST person-specific variable and most likely to be uniform across the population.  DIA is more dependent on the type of insulin being used rather than the person using it.

So I encourage you to set your DIA realistic for the insulin type you are using, and check if your other YDMV variables might need tweaking as a result of changing your DIA.  The work you put into getting those variables more realistic will be rewarded with a much easier bolusing experience.

We’ve regularly been using this “fake extended bolus” technique on Loop now for several weeks and it has been nothing short of remarkable.  The new dynamic carbs model is better able to adjust the insulin delivery (downward pressure) to match observed carb absorption (upward pressure) rather than leaving the upward pressure as a fixed curve.  We have had nearly half a dozen meals over 120g carbs each (donuts, Chinese food, spaghetti) and given single boluses upfront.  Just a single bolus.  I did not calculate or guess how much of the 120g I should bolus for vs try to split bolus for later.  I just told Loop that it was a long meal, took the recommended bolus, and then we walked away to let Loop handle the remaining decisions.  The results have been great.  Very large carb meals peaking between 150-180 mg/dl, no lows, and smooth landings.  Something that used to take a lot of effort and attention has been reduced to a reliable, less stress interaction.

On the left, donuts…large maple bar, large chocolate bar.  Single bolus, Loop calculated…high of about 125mg/dl using a carb absorption time of 2 hours.  On the right, big bowl of spaghetti using carb absorption time of 4 hours.  High of 173 mg/dl, single bolus given, Loop calculated…let Loop do the rest.


For meals that are quicker absorption (where DIA is not an issue because the carbs come in fast enough), Loop functions just like it did before…the full bolus is given upfront and Loop picks up the slop around the messy edges of real life.  But for these big, long meals…if you get your DIA well set, the experience can be one of the most significant reliefs to your t1d burden in a long time.

A few side notes:

  • To fully take advantage of the “fake extended bolus” technique, I did have to increase our max basal rate so that the extended bolus could be delivered in a reasonable time to help control BG spikes later in meal.  It took me some time to feel comfortable raising the max basal rate, since the previous carb absorption model was not forgiving at all…we’d kept the max basal rate fairly restricted to prevent unwanted high temping for quickly rising BGs after a meal.  Our previous max basal rate was 3 u/hr, and now it is 10 u/hr.  Anna’s regular basal rate on average is about 1 u/hr.
  • OpenAPS also uses DIA in calculating your predicted BG curves.  So, while the discussion above is mostly Loop specific, there are many parts that apply to OpenAPS as well.  If you are frustrated and wondering “why is my rig suspending basals so much?”, check if OpenAPS is predicting low BGs before your meal would be done…and ask yourself is it possible that the low BG prediction is due to a DIA set too low for the carb absorption being observed?
  • If you prebolus, make sure you forward-timestamp the carbs when you enter them in the Loop.  That helps Loop better line up the upward and downward curve peaks…and therefore you’ll get a better bolus recommendation upfront.
  • Loop’s Dynamic Carb Absorption model takes your entered carb absorption time and multiplies it by 1.5x as a starting point for its model.  This helps Loop be able to anticipate later carbs (past DIA) but not bolus for them upfront where a low would be more likely otherwise.  This multiplier has been working well for us.  Loop’s dynamic absorption has been able to adjust on-the-fly to situations where the carb absorption was not like we originally anticipated (because hey…that’s life with diabetes).
  • When we started on DCA, we were using 4 hours DIA.  We moved up to 4.5 hours and now are finally pretty pleased at 5 hours.  Our landings from the peak of a meal are more predictably coming in at target at 5 hours vs 4.
  • We still have a growing, hormonal teenager.  We still have to adjust basals regularly during the month.  Our good experiences on Loop still require us to be aware that diabetes presents ever-moving YDMV variables that we need to tweak.  But, it’s easier to be less emotional about that work when the meal bolusing has been made suddenly easier.  Diabetes feels a little lighter on our shoulders.


Loop: Dynamic Carb Absorption

I’m super excited to share Loop’s latest development…it’s a big one! Dynamic Carb Absorption.

So, one of the things that has been most difficult for most new (or little kid) users of Loop app has been how to enter carb absorption times for meals. There’s lots of different strategies I’ve seen employed…breaking meals down into several different carb entries for a single meal, changing carb ratio/ISF settings, or using “fake carbs”. My personal experience was that we had used the default carb absorption times and found we had some significant post-prandial lows due to early high temping.

In the old Loop app, if you entered a longer carb absorption time and had earlier/stronger than expected increase in BGs…Loop would early high temp to cover the “unexpected” spike. Loop also assumed that the later carbs you’d entered were still coming. Basically, Loop was unable to assume that perhaps the carbs were simply acting quicker, and therefore decay them quicker. Conversely the same was true…if you entered a short carb absorption time, but the carbs were actually taking longer, you would likely see some early suspensions and have a BG spike later in the meal.

We figured out that, for us, a default carb absorption time of 90 minutes was working pretty well for our average meals. Fatty and higher carb meals needed some extra attention. We split-bolused a lot and it involved a fair degree of attention to how we entered the carbs (time of entry and carb absorption time) in order to make sure the suggested boluses were also reasonable.

We also had to keep the max basal rate fairly low (about 2.5-3 times the highest basal rate), just in case we had a situation where the carbs absorbed quicker than we’d expected. Didn’t want to let Loop overly correct in those situations.

After a bit of testing and tweaking, we got into a groove…but it wasn’t what I’d call an easy hand-off for a care giver or kid to operate. We still had a lot of “hey mom, how should I bolus for this pizza?” and “Mom, what time do I enter for the carbs?” So, while Anna was good at estimating total carbs for a meal…her actual entry of carbs into Loop app was still difficult by herself.

This difficulty led me to try OpenAPS, especially because of friends who were having troubles with school nurses and caregivers having difficulty in properly entering carbs. OpenAPS was more forgiving of a carb entry and more straight-forward (familiar) for school nurses. They seemed used to “normal” pump bolus wizard entries.

Enter Pete Schwamb. He took on the carb absorption challenge and came up with Dynamic Carb Absorption. You can read more about the idea behind it in Github here. A really good read…highly recommended.

Basically, what Pete’s done is allowed Loop to look at how BGs are responding based on a term called InsulinCounteractionEffect (ICE for short). To quote Pete:

To make an attempt to see how carb absorption is actually progressing, we can take the observed changes in glucose, subtract changes modeled from insulin delivery, and look at the resulting difference, called insulin counteraction effect.

The effects represented by this term are more than just carb effects. It includes exercise, sensitivity changes, and even errors in insulin settings such as basal rate, ISF, etc. However, since the effect of consuming carbohydrates is relatively large, we can still make some useful adjustments to Loop’s carb model by assuming that the effect is mainly carb absorption in the period following recorded meal entries.

What does this mean for us in plain English?  A more forgiving Loop if you get your carb absorption estimate wrong.

Dynamic Carb Absorption version of Loop has been available for development testing since July 1st.  We tried to use it when it was first released, but we were in the midst of trying to cram for how to deal with diabetes camp July 13-19th.  We were trying to figure out if Anna was going to loop, and if so how much and with which system.  She used Loop from September-December 2016 and OpenAPS from January-July 2017.  She’s not keen on change…so trying out a new system right before camp was just not happening.

However, once she came home from camp, we decided to give it a try.  We had a couple days of tweaking her settings after camp, which is typical.  She is quite active and at high altitude for camp, so basals and ISF need a couple days to settle down again.  About 5 days ago, we finally had things dialed in again and I could fairly confidently say that any errors in looping behavior would’ve “not been the fault of bad settings”.  So, it was time to really test.


First test was two large donuts; one chocolate bar and one maple bar.  Typically we have split this bolus up into at least two, sometimes three, boluses.  Not my favorite thing to do.  I keep hoping for the day that Anna will know how to split her boluses herself, but we aren’t there yet.  She still asks for help on about 80% of her higher carb meals that need splits.  Sometimes I get distracted about the timing of the bolus or the eating, and she will go low early after the donuts are eaten because we’ve given too long of a pre-bolus.

So, I did something I thought I’d never do.  I told Anna just to enter 110g of carbs @ carb absorption time of 4 hours, postdate it for 20 minutes for her prebolus time, and give whatever the Loop app recommended for bolus.  It recommended bolusing for 60g of the 110g.  AND THAT WAS THE ONLY BOLUS WE GAVE.

I knew there was some inaccuracy in this entry upfront.  Obviously there are quicker carbs in there as some fraction of the overall carb count…so I knew there was going to be somewhat of a spike after eating.

But, my goal here was more than just BG control.  My goal was “How much can Loop simplify my daughter’s interaction with difficult meals and still maintain decent BGs?”  In other words, can I finally be less involved with my teen’s t1d without risking poor bolusing effects?

SUPER PLEASED with results.  Short version, she did not go above 180 mg/dl and landed after the meal around 100 mg/dl (target is 90 mg/dl).


Do I know that we could do better if I’d manually added a second bolus earlier?  Or if I’d added quicker carbs in addition to the slower carbs?  Sure.  But this accomplished something that I’ve been wanting to see for a long time…a very simplified, safe way my teen could bolus a sugary/fatty meal without danger independently and still get reasonably good (or better) BG results.  She’s not always home.  She’s not always wanting my input on bolusing.  Independence is an important aspect we are trying to nurture.  This experiment gets a big WIN checkmark from me.


Now you’re probably wondering what that new screen is above?  That’s the new carbohydrates effect graph that pops up when you click on the carbs graph.  The graph shows, basically, the expected ICE (insulin counteraction effects) compared to carb absorption effects in grey.  Pete does a great job of explaining the graph in the earlier link, so I won’t repeat it all here.  Suffice to say, I’ve actually found quite a bit of utility in this graph for non-carb stuff too.  For example, the first two days back from camp, Anna’s basals were still too low and our ICE was leading to additional carbs being “counted” at the end of each meal.  These were for meals we had been pretty certain of the carb amounts for.  It was pretty easy to see that we weren’t coming back to target after meal AND that the BG-resistence was being picked up as “additional carbs”.  Knowing that the carb counts were correct, it was pretty easy to hone in on lack of basals as our problem still.  Once we got basals dialed in a little better, the carb counts have been fairly close again between what we enter and what ends up being counted in the ICE at the end of the meal.

IN-N-OUT Cheeseburger

Another favorite meal that we’d previously split and prebolused for.  This time we did all 60g upfront @ carb absorption of 2 hours, and let Loop do the rest.  We started the meal at 115 mg/dl so I figured the lack of split would be ok this time…Loop agreed and provided the whole bolus upfront (vs giving a portion like in the donuts scenario).

About 2 hours after eating, we hit the high point.  Finger sticks showed a max of about 145 mg/dl.  Clearly the meal wasn’t done at the 2 hours we’d initially estimated.  In previous Loop versions, this would’ve meant a need to manually correct to come back to range easier.


By the time the meal ended (over an hour after I’d estimated the meal would take), we settled nice back to target range and didn’t have to manually intervene at all.  All off a single bolus entry.



How about a mixed meal?  Fruit cup, spoonfuls of peanut butter, and leftover fajitas meat.  Yum…the things that teenagers eat on their own while left alone during summer mornings.  Anna estimated 25g @ 90 minutes for this meal.  Peanut butter has always been a favorite of hers, but not so much for me.  Makes the carb absorption times kind of variable.  Some of the quick carbs make it through, but then we get a later rise too.

The dynamic carbs version somehow knew that all those carbs hadn’t ended when Anna had suggested.  By keeping them in the queue, the Loop was more responsive, even while BGs were dropping with IOB, and picked up the later BG rise quite well.  Left us in perfect shape after the meal.


So after 6 days of use, and 4 or 5 of those with our basals fairly well set, here’s how we are looking on Loop DCA version.  We’ve done zero spilt boluses, and only one manual correction (last night her basals doubled in middle of night from hormones).


Anna and I are both really loving the Loop DCA.  She’s enjoying bolusing from phone.  We are still using IFTTT that we’d setup from OpenAPS in order to track site and sensor changes.  I’d say I miss the range of the edison/explorer board that could get us several rooms away…but Anna has easily picked up her old habits of stashing the RileyLink in a pocket again.  We are going to test out tonight how well using multiple RileyLinks in the house may help if she walks around with phone/receiver only.

After testing this out, we’ve felt safe to give our max basal rate room to run a little more for boluses like the two donuts.  We have made our carb ratios just a touch stronger, but I think that’s unrelated to Loop DCA, but rather some hormonal changes that we saw even before we started this system.

All in all, I think this update is going to get a lot of deserved attention and appreciation.  Makes use for kids a heck of a lot easier and safer.  School nurses won’t have nearly the same ability to mess up your kid’s day by a careless carb absorption entry.

Hormones #2

Post-lunch BG climbs to 195, which I knew was unusual given what she’d packed for lunch.  Didn’t notice anything with a crazy carb count on her NS.  But those SMBs were really such a nice visual that my loop and I were on the same page about what to do about it.


I ventured a quick text to check in.  I hate doing that, but she was home from school and I wouldn’t be interrupting class…so I did.  I asked.


Woah.  Wasn’t expecting that one.  We are still a little variable on when that pesky thing is coming…so this caught me off guard.  Three weeks…not four.  Ok.

Things had been so steady for the last several days (*except on beach party with cupcakes, teenagers, and suspended pumps for extended times a couple days ago).  I mean, look…so steady, right?  That was yesterday.

Screen Shot 2017-06-05 at 4.46.05 PM

And then today….with the same food basically.  But that red arrow was The Change.


If I could offer a hug to an inanimate object, it may be going to autosens.  I took a peek to see if things really had been *that steady* or if we had actually been getting a lot of help that I wasn’t aware of.

My suspicions were correct.  What had looked like a calm day, was actually the result of increasing ISF and Basal adjustments, as well as auto lower temp targets, behind the scenes.  From yesterday to today…basals went from 0.8 to 1.05. ISF went from 40 to 30.3.  The storm was held at bay until this afternoon when the big hormones hit just after lunch.


We adjusted her basals to 1.3 (based on where we had to adjust them to last month) and autosens is predicting we may need more…we will let it sit here for a little bit if we need to nudge in that direction in a few hours.

I can’t say how nice it is to take what is normally a horrible time (hormone swings) and make it limited to just a few hours of pain-in-the-butt.  The old way (non-autosens and non-looping) was days of pain.

Under the hood of OpenAPS

(Pull up a chair, this is a bit of an involved post)

UAM is “unannounced meals” feature in oref1 for OpenAPS.  You can read about UAM features and its development in Dana’s blog post here.

Here’s how my thought process has gone on UAM since I first read about it:

1st thought: Oh, I won’t need that since we always enter our carbs and prebolus.  UAM won’t offer me any improvements since we always “announce” our meals.

2nd thought: Well, there are times (ahem, school snack bar) where Anna or I have some hard carb counts.  I wonder if maybe when we were 20% off on a carb count, perhaps UAM might help then?  Because if we are 20% off on a carb count, that would sort of be like having 20% of an unannounced meal, right?  Hmmmm…let’s try enabling it and see.

3rd thought: Wow, that worked really well.  But WHY did it work well?  How is it different?  Oh piss…I’d better roll up my sleeves and look at code.

And that is how I ended up learning more about oref0’s logic for setting temp basal and (now with oref1) setting SMBs.

Side Note: If you care to do the same as I’ve done…the logic for how oref0 sets temp basal and gives SMBs is laid out in a file called determine-basal.js in GitHub.  This same file is pulled into your rig when you build your loop.  I’m not a code person, but a slow and methodical read of the file can provide some insight into the logic for how temp basals are set.  Plus, there’s certain lines in that file that start with “//”…those are plain english notes to help readers understand the code that follows the note.  If you start with the // lines, that may help anchor some of your read of the file.

When I went to the first endo appointment after diagnosis, I was shocked that they didn’t have a flow chart to tell us how to dose insulin.  Like those decisions flow charts that say “if answer is yes, go to this next square…if the answer is no, go to the other square.”  As I came to learn the hard way, the answer to “How much should I dose for a BG of 250 mg/dl?” will have about 18 questions that follow it before you can give an answer.  What’s her ISF?  What’s her IOB?  Is she exercising?  Is her BG rising or falling?  Did she eat recently?  How long ago did she eat?  How much did she eat?  How confident are you in the carb count?  Is she stressed/excited/nervous?   And so on.  It’s no wonder finding a babysitter for a T1D kid is almost impossible.

The same complications exist for loop logic.  Depending on whether BGs are rising/falling/steady, how fast BGs are rising, whether food is at play, and whether temp targets…how does your loop take those into account?   I’d previously heard OpenAPS developer Scott Leibrand refer to “blending” things like this into his loop, but I didn’t quite understand the term until I really looked into the determine-basal.js code.

So how does that blending work?  Traditionally, you’d start loop math using just insulin and carbs to predict future BGs.  You’d approximate how the insulin would behave based on published insulin effectiveness curves (like peaking insulin activity around 60-90 minutes and then tailing off) and you’d approximate carb absorption (like the Loop system does using the model from Think Like A Panceas).  You’d add the downward effect of insulin and the upward effect of carbs and voila…a predicted BG curve blending insulin and carb effects.

But, a good loop will go beyond that simple approximation to try to help with things that are happening outside the perfect-world scenario.  Things like “retrospective correction” and “BG momentum” in Loop system attempt to incorporate the “wtf is happening now? I’m not sure.” part of diabetes into a better BG prediction.

OpenAPS does this refinement through the use of several different predicted BG curves.  Ever wonder WHY OpenAPS has all those purple lines showing in Nightscout?  This is the reason why…those lines are the drivers of the logic.  They help blend the various scenarios about rising/falling/steady BGs, recent food, and activity to come up with a better chosen predicted BG curve.  And a better predicted BG curve should yield a better loop decision…avoiding lows and quicker recovery from high BGs.

Ready for this?  OpenAPS has the following types of “basic” predicted BG curves:

  • IOBpredBGs: based on insulin only
  • COBpredBGs: carbs and insulin together
  • UAMpredBGs: “floating carbs” and insulin together

That’s not the exhaustive list of curves used though…depending on the situation (rising BGs or falling BGs, for example), OpenAPS also does other calculations using the predictedBG curves (for example, minPredBG and avePredBG) to help provide for safe looping.

Basically, determine-basal.js has a whole bunch of “if this (is happening), then do that (use THAT particular predBG curve to determine the delivery of insulin)”.  For example, IF carbs are on-board and UAM and SMB are enabled, and BG is rising but not as much as expected, and IOB is negative, and prediction is above target…THEN use the XXXpredBG curve to calculate how much insulin to deliver.  If you change any one of those IF inputs…like BG is instead dropping and faster than expected…then OpenAPS is going to make a different decision about how to adjust insulin delivery and may use a different predBG curve to do that.

So, determine-basal.js is that complicated set of 18 questions involving “IF this and this and this and this but not that or that, THEN that” that we all used to go through before giving a dose of insulin.  It even has an IF-term called “Deviation” which is basically a measure of how far off expected BG behavior you are.  Looking at the deviation term is a big part of the OpenAPS decision IF-logic.  We’ve all used it before…”dang it, she SHOULD be dropping right now, but she isn’t!”

That’s where UAM and floating carbs come into play in a new way.  Previously, looping was constrained mathematically around meal-times by the amount of carbs entered.  The COBpredBG curve could only go so far in its prediction of BGs because it was limited to the carbs entered.

UAMpredBG is not restricted to the carb entry you’ve provided.  In a way, it doesn’t “trust” your carb entry as much.  It fact-checks your carb entry by looking at deviation comparisons.   More mathematically stated, UAM is predicting the future BGs based on the slope (rate of change in BG) of your actual BGs during meals.  [“during meals” is user-defined as either having carbs on board, an eating soon temp target, and/or a bolus given].  So, if your BGs are rising during a meal and they continue to rise beyond what was predicted on carbs alone (strong deviations happening), UAM is going to carry that prediction forward…regardless of the carbs you entered.  And it will carry that forward until the slope stops and things settle down.  Without UAM, that continued BG prediction up would’ve been restricted shortly after the meal was eaten by the fact that the carbs would’ve decayed ( COB=0 ) fairly quickly based on the rise in BG.

So, do you ever find that perhaps you under-counted carbs?  You’ve watched a meal’s BG climb after unknown sauces and unidentified ingredients were clearly playing a part in the meal?  The recovery to target BG in that situation can be slowed by the fact that the carbs were eventually all “used up” by the loop logic to explain the rise in BG.  Any additional rise the loop had no explanation for, and tended to treat delicately (slowly).

With UAM, the curve says “I can see these deviations were not expected.  I will help.  Even if the deviations go beyond simple explanation of what COB would expect.”  So that mathematical freedom helps for poor carb counting.  (It’s not unlimited freedom, there are still safety mechanisms in place.)

Case in point…that mini McMuffin of unknown carb count.


See how the UAMpredBG is headed to 294, while the other predictions have lower eventual BG predictions?  UAM is taking into account that Deviation of 67 and COB of 16g…saying “wow, you have NOT shown the BG behavior that I would’ve expected at this point in time for the carbs and bolus you’ve told me about.  I’m gonna trust your carb entry less and instead trust the deviations more.  If my predictions are right, you will need 1.85 additional units of insulin to control this unexpected deviation.  But, predictions can change.  So let’s give you a SMB of 0.4 units to help with that right now.  If I’ve overshot my estimate, I can suspend enough basal later to fix. But that 0.4 is a good help right now for your deviations I’m seeing.  Let’s try that, we will regroup with the next BG and see where you are.”

The next BG reading comes in and loop has some new information to consider.  BG has slowed down and there’s more insulin on board from the 0.4 SMB.

Screen Shot 2017-05-22 at 11.16.08 AM

Deviation is now a smaller number (the slope of the rising BGs has decreased), we are moving closer to what the expected behavior should be.  In fact, the UAMpredBG curve now predicts an eventual BG of 104 and the insulin required is now -0.12 units.  So, loop will suspend basals and wait for the next BG to come in…and go through all of its IFs and THENs again before deciding what to do with insulin.  The loop is beginning to be able to trust cob again; it has delivered enough insulin to cover the carbs that we undercounted and, through SMBs help too, we are going to spend less time out of range.

What about situations where you OVER counted carbs?  Will UAM be able to help there too?  Yes.  When UAM is not seeing enough carb absorption compared to what you’ve told it to expect (“hey, you promised me 25g carbs and I’m only seeing enough BG impact to trust that you ate 10g of carbs”), then the loop will hold off on basal insulin and dosing until the BGs catch up.  (See…it’s comparing those COBpredBG curves with the UAMpredBG curves to make decisions.  All those little purple lines and deviation values are part of the logic sequence to deliver insulin.)

Because UAMpredBG curve is not limited so much by your actual carb entry, it will tend to have a much more variable prediction after each new BG entry.  It will predict very high eventual BG if your BG is strongly rising, and then it will predict lower BG if your BG is dropping.  So, if and when, you decide to enable UAM…don’t be surprised by seeing an ever-changing UAM curve, that’s an expected result since it isn’t quite so restricted by your carb entry.

As I understand it, it took several iterations for Scott and Dana to figure out the proper blending (IFs and THENs) of UAM into the oref0 determine-basal.js code.  Then there’s been many early users that have put it to the test to validate or improve the blending.

Where I’d previously thought that UAM had very little value, because we always enter our meals and prebolus…turns out I was wrong.  I’m not a carb-counting expert.  I get it wrong sometimes.  And UAM helps mop-up my harder carb counts, in both directions.  When I’m right on carb counts, UAM plays almost no role…but with UAM I’m not going to be nearly as BG-impacted when I do get things wrong.