Insulin Concentration

The following plot shows three day’s worth of insulin boluses. (What’s a bolus? It’s the insulin dose given at mealtime or as a correction to bring down blood sugar. It differs from the continuously delivered background insulin by being a much larger dose and being manually delivered.)


The spikes are the “normal” boluses, and there are about a dozen per day. (The one rectangular box on the 9th is a “square bolus” delivered over an extended period.) It’s kind of amazing how quickly insulin gets from where it’s delivered subcutaneously to the blood stream, but it isn’t instantaneous. And several hours pass between when the insulin enters the blood stream and when it is fully cleared through metabolism or by the liver. (Yay, liver!)

In signal processing terms, the normal boluses are essentially impulse signals that yield a response. (You can see the response curve in a previous post.) Here are the impulse responses for the normal boluses.


But this isn’t exactly how insulin works. All of those curves build on top of each other. Figuring out how to add all of those contributions into one “signal” is my project for the evening. When I asked a coworker about a good way to do this today, he suggested convolution, and then we prototyped a couple things. Now I’m working on doing that. It’s supposed to look a bit like this . . .


. . . but it isn’t quite right, since it seems shifted earlier in time relative to the boluses:


I will provide an update when we figure it out.

Updated a few minutes later: Of course! Because the convolution operation acts symmetrically about the impulse, the kernel needs to be pre-padded with an equal number of zeros. That shifts the result appropriately.


And some code. . . .

timelineAll = load('database_all.mat');
timelineSubset = findByDate(timelineAll, '2013-06-09', '2013-06-12');
timeStamps = [timelineSubset.bolusEvents{:,1}];
bolusAmts = [timelineSubset.bolusEvents{:,3}];

% Create a linearly spaced timeline.
resolution = 10;
spacing = resolution/60/24;

inputTime = floor(min(timeStamps)):spacing:ceil(max(timeStamps));
inputSignal = zeros(size(inputTime));

% Put the normal boluses into the signal.
for p = 1:numel(bolusAmts)
    % Find closest inputTime location to this time.
    absoluteTime = timeStamps(p);
    fractionalPart = absoluteTime - floor(absoluteTime);
    fractionalPart = round(fractionalPart * 24 * 6) / 6 / 24;
    roundedTime = floor(absoluteTime) + fractionalPart;
    
    % Assign the bolus.
    inputSignal(inputTime == roundedTime) = bolusAmts(p);
end

% Resample the insulin action curve.
scaleFactors = [0.0, 0.73, 1.0, 0.93, 0.67, 0.47, 0.27, 0.22, 0.18, 0.13, 0.07];
curveTimes = 0:0.5:5;
resampledCurveTimes = 0:(resolution/60):5;
resampledScaleFactors = interp1(curveTimes, scaleFactors, resampledCurveTimes, 'cubic');
resampledScaleFactors = [zeros(size(resampledScaleFactors)) resampledScaleFactors];

%concentration = conv(inputSignal, resampledScaleFactors, 'same') * 0.37;
concentration = conv(inputSignal, resampledScaleFactors, 'same');

figure;
stem(inputTime(inputSignal~=0), inputSignal(inputSignal~=0)); datetick
hold on
plot(inputTime, concentration, 'r'); datetick;
title('Cumulative insulin concentration')
This entry was posted in Data-betes, Diabetes, Fodder for Techno-weenies, MATLAB. Bookmark the permalink.

5 Responses to Insulin Concentration

  1. scully says:

    this is absolutely fascinating!!!! you’ve got mad skillz!

  2. StephenS says:

    Jeff, I’m really enjoying the work that you’re putting in on this. I thought I had a handle on all of this, but that last graph was an eye opener. Thanks

  3. Um, Yeah! I TOTALLY understood ALL of that. Even the code.

    Seriously, dude. You are one smart cookie. I like knowing smart cookies. :-)

  4. Jansen says:

    Hi Jeff,

    I am doing a project similar to this using an inhaled medication with a half life of twelve hours and usually twice daily dosing. I think your code would be very useful for plotting the cumulative concentration of the drug but I cant seem to get it to work. Do you mind sending your “database_all.mat” file because I think the problem is in how the data is entered.

    Thanks,
    J.

  5. Tom says:

    Hi Jeff,
    This is wonderful code snippet. But what about square boluses? It looks like they’re ignored. I don’t have the coding skill to model them in MATLAB. If you addressed them later I’d love to see the code.
    Tom

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>