Esempio n. 1
0
def test_compute_iob_single_step_net():
    """
    Test IOB computing for a net insulin profile with a single step.
    """

    # Define a DIA
    DIA = 3.0

    # Get an IDC
    walsh = idc.WalshIDC(DIA)

    # Create net insulin profile
    netInsulin = net.Net()
    netInsulin.t = np.array([-DIA, 0])
    netInsulin.y = np.array([1, 1])

    # Define integral over single step
    walshIntegrals = np.array([1.45532, 0])

    expectedIOB = np.sum(netInsulin.y * walshIntegrals)
    IOB = calculator.computeIOB(netInsulin, walsh)

    assert isEqual(IOB, expectedIOB)

    # Redefine net insulin profile that corresponds to only scheduled basals
    # (there should be no insulin on board)
    netInsulin.t = np.array([-DIA, 0])
    netInsulin.y = [0, 0]

    expectedIOB = 0
    IOB = calculator.computeIOB(netInsulin, walsh)

    assert isEqual(IOB, expectedIOB)
Esempio n. 2
0
def computeIOBs(t, T, Net, IDC):
    """
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        COMPUTEIOBS
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        This function computes the IOB at a given time.
    """

    # Initialize IOBs
    IOBs = []

    # Compute IOB for each BG
    for i in range(len(T)):

        # Copy net insulin profile
        net_ = copy.deepcopy(Net)

        # Cut it for current IOB computation
        start = T[i] - datetime.timedelta(hours=IDC.DIA)
        end = T[i]
        net_.cut(start, end)
        net_.normalize()

        # Compute corresponding IOB, store, and show it
        IOB = calculator.computeIOB(net_, IDC)
        IOBs += [IOB]
        print "IOB(" + lib.formatTime(end) + ") = " + fmt.IOB(IOB)

    return IOBs
Esempio n. 3
0
def computeExpectedBGDeltas(t, T, Net, IDC, ISFs):
    """
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        COMPUTEEXPECTEDBGDELTAS
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        This function computes an array of expected BG variations, given an IDC
        and a net insulin profile.
    """

    # Initialize expected BG deltas
    expectedDeltaBGs = []

    # Compute expected BG deltas
    for i in range(len(T) - 1):

        # Copy net insulin profile
        net_ = copy.deepcopy(Net)

        # Cut it for current IOB computation
        start = T[i] - datetime.timedelta(hours=IDC.DIA)
        end = T[i]
        net_.cut(start, end)
        net_.normalize()

        # Compute corresponding IOB
        IOB0 = calculator.computeIOB(net_, IDC)

        # Move net insulin profile into the past by the time that passes until
        # next BG value
        dt = t[i + 1] - t[i]
        net_.shift(-dt)

        # Compute new IOB, and the difference with the last one
        IOB1 = calculator.computeIOB(net_, IDC)
        dIOB = IOB1 - IOB0

        # Get current ISF and compute dBG using dIOB
        # NOTE: there might be some error slipping in here if ISF changes
        # between the two IOBs
        ISF = ISFs.f(t[i])
        dBG = dIOB * ISF

        # Store and show expected BG delta
        expectedDeltaBGs += [dBG]
        print "dBG(" + lib.formatTime(start) + ") = " + fmt.BG(dBG)

    return expectedDeltaBGs
Esempio n. 4
0
    def build(self, net, IDC, dt, show=False):
        """
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            BUILD
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Build prediction profile of IOB decay.
        """

        # Info
        Logger.debug("Building 'FutureIOB'...")

        # Reset components
        self.reset()

        # Define time references
        self.define(net.end, IDC.DIA, dt)

        # Copy net insulin profile
        net = copy.deepcopy(net)

        # Compute IOB decay
        for _ in self.t:

            # Compute new IOB and store it
            self.y += [calculator.computeIOB(net, IDC)]

            # Move net insulin profile into the past (only normalized axis is
            # needed for IOB computation)
            net.shift(-self.dt)

        # Derivate
        self.derivate()

        # Store current IOB
        self.store()

        # Show
        if show:
            self.show()
Esempio n. 5
0
def test_compute_iob_multiple_steps_net():
    """
    Test IOB computing for a net insulin profile with multiple steps.
    """

    # Define a DIA
    DIA = 3.0

    # Get an IDC
    walsh = idc.WalshIDC(DIA)

    # Create net insulin profile
    netInsulin = net.Net()
    netInsulin.t = np.array([-DIA, -2, -1, 0])
    netInsulin.y = np.array([2, -0.5, 3, 1])

    # Define part integrals (one for each step)
    walshIntegrals = np.array([0.129461, 0.444841, 0.881021, 0])

    expectedIOB = np.sum(netInsulin.y * walshIntegrals)
    IOB = calculator.computeIOB(netInsulin, walsh)

    assert isEqual(IOB, expectedIOB)
Esempio n. 6
0
    def build(self, past, net, IDC, futureISF, dt, show=False):
        """
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            BUILD
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Predict natural IOB decay and compute resulting BG variation at the
            same time, using ISF profile and IDC. The formula used to compute it
            is given by:

                dBG = SUM_t' ISF(t') * dIOB(t')

            where t' represents the value of a given time step, dIOB(t') the
            drop in active insuline (IOB) during that time, and ISF(t') the
            corresponding insulin sensitivity factor. The variation in BG after
            the end of insulin activity is given by dBG.
        """

        # Info
        Logger.debug("Building 'FutureBG'...")
        Logger.debug("Step size: " + str(self.dt) + " h")

        # Ensure there is one BG recent enough to accurately predict decay
        calculator.countValidBGs(past, 15, 1)

        # Reset previous BG predictions
        self.reset()

        # Define time references
        self.define(net.end, IDC.DIA, dt)

        # Initialize BG
        BG = past.y[-1]

        # Store initial (most recent) BG
        self.y.append(BG)

        # Copy net insulin profile
        net = copy.deepcopy(net)

        # Compute initial IOB
        IOBs = [calculator.computeIOB(net, IDC)]

        # Compute dBG
        for i in range(len(self.t) - 1):

            # Compute start/end of current step
            [t0, t1] = [self.t[i], self.t[i + 1]]

            # Generate time axis associated with ISF changes over current step
            t = [t0]
            t += list(filter(lambda t_: t0 < t_ < t1, futureISF.t))
            t += [t1]

            # Loop on ISF changes
            for j in range(len(t) - 1):

                # Move net insulin profile into the past
                dt = t[j + 1] - t[j]
                net.shift(-dt)

                # Compute new IOB and difference with last one
                IOB = calculator.computeIOB(net, IDC)
                dIOB = IOB - IOBs[-1]
                IOBs += [IOB]

                # Compute dBG for current step and corresponding expected BG
                dBG = futureISF.f(t[j]) * dIOB
                BG += dBG

            # Store BG at end of current step
            self.y += [BG]

        # Derivate
        self.derivate()

        # Show
        if show:
            self.show()
Esempio n. 7
0
    def autosens(self, now, t = 24):

        """
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            AUTOSENS
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        """

        # Define past reference time
        past = now - datetime.timedelta(hours = t)

        # Define DIA as a datetime timedelta object
        dia = datetime.timedelta(hours = self.DIA)

        # Instanciate profiles
        profiles = {"IDC": IDC.WalshIDC(self.DIA),
                    "Suspend": None,
                    "Resume": None,
                    "Basal": None,
                    "TB": None,
                    "Bolus": None,
                    "Net": None,
                    "ISF": ISF.ISF(),
                    "PastBG": BG.PastBG()}

        # Build past BG profile
        profiles["PastBG"].build(past, now)
        
        # Build past ISF profile
        profiles["ISF"].build(past, now)

        # Reference to BG time axis
        T = profiles["PastBG"].T

        # Initialize IOB arrays
        IOBs = []

        # Get number of BGs
        n = len(T)

        # Compute IOB for each BG
        for i in range(n):

            # Reset necessary profiles
            profiles["Suspend"] = suspend.Suspend()
            profiles["Resume"] = resume.Resume()
            profiles["Basal"] = basal.Basal()
            profiles["TB"] = TB.TB()
            profiles["Bolus"] = bolus.Bolus()
            profiles["Net"] = net.Net()

            # Build net insulin profile
            profiles["Net"].build(T[i] - dia, T[i], profiles["Suspend"],
                                                    profiles["Resume"],
                                                    profiles["Basal"], 
                                                    profiles["TB"],
                                                    profiles["Bolus"])

            # Do it
            IOBs.append(calc.computeIOB(profiles["Net"], profiles["IDC"]))

            # Show IOB
            print "IOB(" + lib.formatTime(T[i]) + ") = " + fmt.IOB(IOBs[-1])
Esempio n. 8
0
File: BG.py Progetto: mm22dl/MeinKPS
    def build(self, dt, net, IDC, futureISF, past):

        """
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            BUILD
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Predict natural IOB decay and compute resulting BG variation at the
            same time, using ISF profile and IDC. The formula used to compute it
            is given by:

                dBG = SUM_t' ISF(t') * dIOB(t')

            where t' represents the value of a given time step, dIOB(t') the
            drop in active insuline (IOB) during that time, and ISF(t') the
            corresponding insulin sensitivity factor. The variation in BG after
            the end of insulin activity is given by dBG.
        """

        # Give user info
        Logger.debug("Building 'FutureBG'...")

        # Ensure there is one BG recent enough to accurately predict decay
        calc.countValidBGs(past, 15, 1)

        # Initialize BG
        BG = past.y[-1]

        # Give user info
        Logger.debug("Step size: " + str(self.dt) + " h")
        Logger.debug("Initial BG: " + str(BG) + " " + self.units)

        # Reset previous BG predictions
        self.reset()

        # Define time references
        self.define(net.end, IDC.DIA, dt)

        # Store initial (most recent) BG
        self.y.append(BG)

        # Copy net insulin profile
        net = copy.deepcopy(net)

        # Compute initial IOB
        IOB0 = calc.computeIOB(net, IDC)

        # Read number of steps in prediction
        n = len(self.t) - 1

        # Read number of entries in net insulin profile
        m = len(net.t)

        # Read number of entries in ISF profile
        l = len(futureISF.t)

        # Compute dBG
        for i in range(n):

            # Compute start/end of current step
            t0 = self.t[i]
            t1 = self.t[i + 1]

            # Initialize time axis associated with ISF changes
            t = []

            # Define start time
            t.append(t0)

            # Fill it with ISF change times
            for j in range(l):

                # Change contained within current step
                if t0 < futureISF.t[j] < t1:

                    # Add it
                    t.append(futureISF.t[j])

            # Define end time
            t.append(t1)

            # Loop on ISF changes
            for j in range(len(t) - 1):

                # Define step
                dt = t[j + 1] - t[j]

                # Move net insulin profile into the past
                for k in range(m):

                    # Update normalized time axis
                    net.t[k] -= dt

                # Compute new IOB
                IOB = calc.computeIOB(net, IDC)

                # Compute dIOB
                dIOB = IOB - IOB0

                # Update IOB
                IOB0 = IOB

                # Compute dBG for current step
                dBG = futureISF.f(t[j]) * dIOB

                # Compute expected BG
                BG += dBG

            # Store BG at end of current step
            self.y.append(BG)

        # Normalize
        self.normalize()

        # Derivate
        self.derivate()

        # Show
        self.show()