Source code for Simulator.UVAPadova.UVAPadovaSimulator

import numpy as np
from matplotlib import pyplot as plt
from ..OESimulator.SimulationData.Scenario import Scenario
from ..OESimulator.DataProcessor import DataProcessor
from .VirtualPatientT1DMS import VirtualPatientT1DMS
import matlab.engine
import time


[docs]class UvaPadovaSimulator: """ This class can be store the current state of a simulation and can extend it by 5 minutes per step. Note: This class was created exclusively to serve the API. Args: patient (obj) : A VirtualPatientT1DMS object, which represents a virtual patient and controls the MATLAB engine. scenario (obj): A Scenario object, which provides a storage and interface for the simulation related information. chLostFlag (bool): A flag which indicates whether the meal could be considered according to the rules of the UvaPadovaSimulator or not. tEndReal (int): The duration of the simulation in minutes. i_times (list(int)): The list of minutes when was insulin intake. meals (list(float)): The list of the amounts of carbohydrate taken. m_times (list(int)): The list of minutes when was carbohydrate intake. insulins (list(float)): The list of the amounts of insulin taken. sensor (str): The type of the CGM sensor currently in use. Defaults to 'guardianRT.scs' pump (str): The type of the insulin pump currently in use. Defaults to 'Generic_1.pmp' """ def __init__(self, patient_name: str): self.patient = VirtualPatientT1DMS(patient_name=patient_name, BGinit=matlab.double([])) self.scenario = None self.chLostFlag = False self.tEndReal = 0 self.i_times = list() self.meals = list() self.m_times = list() self.insulins = list() self.sensor = 'guardianRT.scs' self.pump = 'Generic_1.pmp'
[docs] def doSimulation(self, carbohydrate: float, insulin: float): """ This method extends the initialized simulation by 5 minutes. The method invokes the MATHLAB engine with an extended Scenario. Args: carbohydrate (float): The amount of carbohydrate intake, in the last five minutes (in grams). Zero if there wasn't carbohydrate intake. insulin (float): The amount of insulin intake, in the last five minutes (in unites). Zero if there wasn't insulin intake. Returns: The blood glucose level value at the end of the simulation. """ self.chLostFlag = False # reset the flag self.__buildScenario(carbohydrate, insulin) T1DMSprocessor = DataProcessor() T1DMSdata, patient_data = T1DMSprocessor.processData(scenario=self.scenario) self.patient.simulatePatient(simulation_data=T1DMSdata) return self.patient.bg[self.tEndReal][0]
def __buildScenario(self, carbohydrate: float, insulin: float): """This method builds and the extended Scenario, considering the simulation rules of UvaPadova Simulator. Args: carbohydrate (float): The amount of carbohydrate intake, in the last five minutes (in grams). Zero if there wasn't carbohydrate intake. insulin (float): The amount of insulin intake, in the last five minutes (in unites). Zero if there wasn't insulin intake. """ # Update values self.tEndReal += 5 if carbohydrate != 0 and self.__newChIsEnabled(): self.m_times.append(self.tEndReal) self.meals.append(carbohydrate) if insulin != 0: self.i_times.append(self.tEndReal) self.insulins.append(insulin) if self.tEndReal < 30: tend = 30 else: tend = self.tEndReal # Create Scenario self.scenario = Scenario(0, tend, "t1dms") self.scenario.Ts = 1 self.scenario.setManualMealScheme(meal_times=tuple(self.m_times), meal_values=tuple(self.meals), unit='g') self.scenario.setManualBolusScheme(bolus_times=tuple(self.i_times), bolus_values=tuple(self.insulins), unit='U') self.scenario.setManualBasalInsulin(0.0, unit=r"U/hr") self.scenario.setHardware(sensor=self.sensor, pump=self.pump) self.scenario.setParamsT1DMS() def __newChIsEnabled(self) -> bool: """This method checks the meal could be considered according to the rules of the UvaPadova Simulator or not and sets the chLostFlag's value. Returns: bool: True if the carbohydrate intake can be considered. False otherwise. """ if self.tEndReal >= 60 and (not self.m_times or (self.tEndReal - self.m_times[-1]) >= 60): return True else: self.chLostFlag = True return False