Line by line parsing of determine-basal.js in Android APS

Let's take a look at the file determine-basal.js line by line.

Comment and License

/*
  Determine Basal

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/
  • Description: A standard comment block that contains information about the MIT license and a disclaimer.

Import function round_basal

var round_basal = require('../round-basal');
  • Description: Importing function round_basalwhich is used to round the basal insulin dose based on the user's profile.

round function: Rounding off values

function round(value, digits)
{
    if (!digits) { digits = 0; }
    var scale = Math.pow(10, digits);
    return Math.round(value * scale) / scale;
}
  • Description: This function rounds the passed value. value up to the specified number of decimal places (digits). If digits not specified, the value is rounded to the nearest whole number.

calculate_expected_delta function: Calculate the expected change in glucose levels

function calculate_expected_delta(target_bg, eventual_bg, bgi) {
    var five_min_blocks = (2 * 60) / 5;
    var target_delta = target_bg - eventual_bg;
    return round(bgi + (target_delta / five_min_blocks), 1);
}
  • Description: This function calculates the expected change in glucose levels (expectedDelta) based on current insulin sensitivity (BGI) and the difference between target and final predicted glucose levels.

convert_bg function: Convert glucose values

function convert_bg(value, profile)
{
    if (profile.out_units === "mmol/L")
    {
        return round(value / 18, 1).toFixed(1);
    }
    else
    {
        return Math.round(value);
    }
}
  • Description: This function converts the blood glucose level from mg/dL to mmol/L if the profile specifies mmol/L. Otherwise, the value is returned to mg/dL.

enable_smb function: Enable SMB (Super Micro Bolus) function

function enable_smb(
    profile,
    microBolusAllowed,
    meal_data,
    target_bg
) {
    if (!microBolusAllowed) {
        console.error("SMB disabled (!microBolusAllowed)");
        return false;
    } else if (!profile.allowSMB_with_high_temptarget && profile.temptargetSet && target_bg > 100) {
        console.error("SMB disabled due to high temptarget of", target_bg);
        return false;
    } else if (meal_data.bwFound === true && profile.A52_risk_enable === false) {
        console.error("SMB disabled due to Bolus Wizard activity in the last 6 hours.");
        return false;
    }
    if (profile.enableSMB_always === true) {
        if (meal_data.bwFound) {
            console.error("Warning: SMB enabled within 6h of using Bolus Wizard: be sure to easy bolus 30s before using Bolus Wizard");
        } else {
            console.error("SMB enabled due to enableSMB_always");
        }
        return true;
    }
    if (profile.enableSMB_with_COB === true && meal_data.mealCOB) {
        if (meal_data.bwCarbs) {
            console.error("Warning: SMB enabled with Bolus Wizard carbs: be sure to easy bolus 30s before using Bolus Wizard");
        } else {
            console.error("SMB enabled for COB of", meal_data.mealCOB);
        }
        return true;
    }
    if (profile.enableSMB_after_carbs === true && meal_data.carbs) {
        if (meal_data.bwCarbs) {
            console.error("Warning: SMB enabled with Bolus Wizard carbs: be sure to easy bolus 30s before using Bolus Wizard");
        } else {
            console.error("SMB enabled for 6h after carb entry");
        }
        return true;
    }
    if (profile.enableSMB_with_temptarget === true && (profile.temptargetSet && target_bg < 100)) {
        if (meal_data.bwFound) {
            console.error("Warning: SMB enabled within 6h of using Bolus Wizard: be sure to easy bolus 30s before using Bolus Wizard");
        } else {
            console.error("SMB enabled for temptarget of", convert_bg(target_bg, profile));
        }
        return true;
    }

    console.error("SMB disabled (no enableSMB preferences active or no condition satisfied)");
    return false;
}
  • Description: This feature determines whether Super Micro Bolus (SMB) mode can be enabled based on various conditions such as carbohydrate on board (COB), use of Bolus Wizard, and other user profile settings.

Main function determine_basal

var determine_basal = function determine_basal(glucose_status, currenttemp, iob_data, profile, autosens_data, meal_data, tempBasalFunctions, microBolusAllowed, reservoir_data, currentTime, flatBGsDetected) {
    var rT = {}; // short for requestedTemp
  • Description: Main function determine_basal takes a number of parameters that include data about the current glucose level, active insulin, user profile, and other data. It returns an object rTcontaining the results of the function.

Determining execution time

    var deliverAt = new Date();
    if (currentTime) {
        deliverAt = new Date(currentTime);
    }
  • Description: This part of the code sets the current time when the insulin delivery will be performed. If specified currentTimeit is used instead of the system time.

Checking the correctness of the profile

    if (typeof profile === 'undefined' || typeof profile.current_basal === 'undefined') {
        rT.error="Error: could not get current basal rate";
        return rT;
    }
    var profile_current_basal = round_basal(profile.current_basal, profile);
    var basal = profile_current_basal;
  • Description: Checks if the profile is correct and if the current basal rate is defined. If not, the function returns an error. If yes, the basal rate is rounded and stored in a variable. basal.

Time and Glucose Data Analysis

    var systemTime = new Date();
    if (currentTime) {
        systemTime = currentTime;
    }
    var bgTime = new Date(glucose_status.date);
    var minAgo = round((systemTime - bgTime) / 60 / 1000, 1);

    var bg = glucose_status.glucose;
    var noise = glucose_status.noise;
  • Description: The time of glucose data acquisition and the time difference between the current moment and the time of data acquisition are calculated (minAgo). The current glucose level is also determined (bg) and the noise level of CGM data (noise).

Checking the relevance of glucose data

    if (bg <= 10 || bg === 38 || noise >= 3) {  
        rT.reason = "CGM is calibrating, in ??? state, or noise is high";
    }
    if (minAgo > 12 || minAgo < -5) {  
        rT.reason = "If current system time " + systemTime + " is correct, then BG data is too old.";
    } else if (bg > 60 && flatBGsDetected) {
        if (glucose_status.last_cal && glucose_status.last_cal < 3) {
            rT.reason = "CGM was just calibrated";
        } else {
            rT.reason = "Error: CGM data is unchanged for the past ~45m";
        }
    }
  • Description: Checks whether the glucose data is up-to-date, whether there is too much noise or whether the data has not been updated for a long time. If the data is incorrect, an error message is written.

Handling old or incorrect glucose data

    if (bg <= 10 || bg === 38 || noise >= 3 || minAgo > 12 || minAgo < -5 || (bg > 60 && flatBGsDetected)) {
        if (currenttemp.rate > basal) { 
            rT.reason += ". Re

placing high temp basal of " + currenttemp.rate + " with neutral temp of " + basal;
            rT.deliverAt = deliverAt;
            rT.temp = 'absolute';
            rT.duration = 30;
            rT.rate = basal;
            return rT;
        } else if (currenttemp.rate === 0 && currenttemp.duration > 30) { 
            rT.reason += ". Shortening " + currenttemp.duration + "m long zero temp to 30m. ";
            rT.deliverAt = deliverAt;
            rT.temp = 'absolute';
            rT.duration = 30;
            rT.rate = 0;
            return rT;
        } else {
            rT.reason += ". Temp " + currenttemp.rate + " <= current basal " + round(basal, 2) + "U/hr; doing nothing. ";
            return rT;
        }
    }
  • Description: This block checks the conditions under which the temporary basal rate can be adjusted or reset based on the relevance of the data. If the data is not relevant, the basal rate is adjusted based on the current conditions.

Determining target glucose values ​​and calculating sensitivity

    var max_iob = profile.max_iob;

    var target_bg;
    var min_bg;
    var max_bg;
    if (typeof profile.min_bg !== 'undefined') {
        min_bg = profile.min_bg;
    }
    if (typeof profile.max_bg !== 'undefined') {
        max_bg = profile.max_bg;
    }
    if (typeof profile.min_bg !== 'undefined' && typeof profile.max_bg !== 'undefined') {
        target_bg = (profile.min_bg + profile.max_bg) / 2;
    } else {
        rT.error="Error: could not determine target_bg. ";
        return rT;
    }

    var sensitivityRatio;
    var high_temptarget_raises_sensitivity = profile.exercise_mode || profile.high_temptarget_raises_sensitivity;
    var normalTarget = 100;
    if (profile.half_basal_exercise_target) {
        var halfBasalTarget = profile.half_basal_exercise_target;
    } else {
        halfBasalTarget = 160;
    }
  • Description: Determines minimum, maximum and target glucose values ​​based on the user profile. A sensitivity factor (sensitivityRatio), which can be adjusted based on conditions such as exercise regimen or glucose targets.

Implementation of Dynamic ISF and Sensitivity Calculation

    console.error("---------------------------------------------------------");
    console.error(" Dynamic ISF version Beta 2.0 ");
    console.error("---------------------------------------------------------");

    var variable_sens = profile.variable_sens;
    var TDD = profile.TDD;
    var insulinDivisor = profile.insulinDivisor;
  • Description: This block of code is for dynamically calculating insulin sensitivity (ISF). The variables used for the calculations are defined here, such as the sensitivity variable (variable_sens), total daily dose of insulin (TDD) and insulin divider (insulinDivisor).

Determination of the sensitivity coefficient

    if (high_temptarget_raises_sensitivity && profile.temptargetSet && target_bg > normalTarget
        || profile.low_temptarget_lowers_sensitivity && profile.temptargetSet && target_bg < normalTarget) {
        var c = halfBasalTarget - normalTarget;
        sensitivityRatio = c / (c + target_bg - normalTarget);
        sensitivityRatio = Math.min(sensitivityRatio, profile.autosens_max);
        sensitivityRatio = round(sensitivityRatio, 2);
        console.log("Sensitivity ratio set to " + sensitivityRatio + " based on temp target of " + target_bg + "; ");
    } else if (typeof autosens_data !== 'undefined' && autosens_data) {
        sensitivityRatio = autosens_data.ratio;
        console.log("Autosens ratio: " + sensitivityRatio + "; ");
    }
    if (sensitivityRatio) {
        basal = profile.current_basal * sensitivityRatio;
        basal = round_basal(basal, profile);
        if (basal !== profile_current_basal) {
            console.log("Adjusting basal from " + profile_current_basal + " to " + basal + "; ");
        } else {
            console.log("Basal unchanged: " + basal + "; ");
        }
    }
  • Description: In this block the sensitivity coefficient (sensitivityRatio), which can be adjusted depending on target glucose values ​​and autosense data. If the coefficient is changed, the basal dose is also recalculated.

Adjusting target glucose values

    if (profile.temptargetSet) {
        // Temp target set, no adjustment
    } else if (typeof autosens_data !== 'undefined' && autosens_data) {
        if (profile.sensitivity_raises_target && autosens_data.ratio < 1 || profile.resistance_lowers_target && autosens_data.ratio > 1) {
            min_bg = round((min_bg - 60) / autosens_data.ratio) + 60;
            max_bg = round((max_bg - 60) / autosens_data.ratio) + 60;
            var new_target_bg = round((target_bg - 60) / autosens_data.ratio) + 60;
            new_target_bg = Math.max(80, new_target_bg);
            if (target_bg === new_target_bg) {
                console.log("target_bg unchanged: " + new_target_bg + "; ");
            } else {
                console.log("target_bg from " + target_bg + " to " + new_target_bg + "; ");
            }
            target_bg = new_target_bg;
        }
    }
  • Description: In this block, the target glucose values ​​(min_bg, max_bg, target_bg) can be adjusted based on the sensitivity factor to account for changes in the user's sensitivity or tolerance.

Handling IOB data errors

    if (typeof iob_data === 'undefined') {
        rT.error="Error: iob_data undefined. ";
        return rT;
    }

    var iobArray = iob_data;
    if (typeof (iob_data.length) && iob_data.length > 1) {
        iob_data = iobArray[0];
    }

    if (typeof iob_data.activity === 'undefined' || typeof iob_data.iob === 'undefined') {
        rT.error="Error: iob_data missing some property. ";
        return rT;
    }
  • Description: This block checks for the presence and correctness of insulin on board (IOB) data. If the data is missing or incorrect, the function returns an error.

Reviewing glucose changes and processing temporary basal rates

    var tick;
    if (glucose_status.delta > -0.5) {
        tick = "+" + round(glucose_status.delta, 0);
    } else {
        tick = round(glucose_status.delta, 0);
    }
    var minDelta = Math.min(glucose_status.delta, glucose_status.short_avgdelta);
    var minAvgDelta = Math.min(glucose_status.short_avgdelta, glucose_status.long_avgdelta);
    var maxDelta = Math.max(glucose_status.delta, glucose_status.short_avgdelta, glucose_status.long_avgdelta);
  • Description: Various parameters related to the change in glucose levels are calculated here: current change (delta), minimum and maximum changes based on short and long averages.

Reviewing the last temporary basal rate

    var lastTempAge;
    if (typeof iob_data.lastTemp !== 'undefined') {
        lastTempAge = round((new Date(systemTime).getTime() - iob_data.lastTemp.date) / 60000);
    } else {
        lastTempAge = 0;
    }
    var tempModulus = (lastTempAge + currenttemp.duration) % 30;
    console.error("currenttemp:", round(currenttemp.rate, 2), "lastTempAge:", lastTempAge, "m", "tempModulus:", tempModulus, "m");
    rT.temp = 'absolute';
    rT.deliverAt = deliverAt;
  • Description: This block looks at the age of the last temp basal rate and the current temp rate to determine if they need to be adjusted.

Considering insulin sensitivity and calculating predicted insulin exposure

    var bgi = round((-iob_data.activity * sens * 5), 2);
    var deviation = round(30 / 5 * (minDelta - bgi));
    if (deviation < 0) {
        deviation = round((30 / 5) * (minAvgDelta - bgi));
        if (deviation < 0) {
            deviation = round((30 / 5) * (glucose_status.long_avgdelta - bgi));
        }
    }
    var naive_eventualBG = round(bg - (iob_data.i

ob * sens));
    var eventualBG = naive_eventualBG + deviation;
  • Description: Calculates the predicted change in glucose levels based on insulin activity (bgi) and deviations (deviation). The final predicted glucose level is also calculated (eventualBG).

This line-by-line analysis continues through the code and determines how the program processes data, predicts glucose levels, calculates the required insulin doses, and determines what actions to take based on those predictions.

If you need more detail or clarification on specific lines, please let me know.

Similar Posts

Leave a Reply

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