def adjust_sleep(self, data, no_variation=False): """ This function adjusts the household parameters to reflect the sampled parameters \ (mean and standard deviation of start time, end time, and \ duration, respectively), from the CHAD data for the sleeping \ activity. :param data: relevant parameters for each person in the household for \ sleeping. The tuple contains the following: mean start time, standard \ deviation of start time, mean end time, standard deviation of end time, mean duration, \ and standard deviation of duration for each person in the household. :type data: tuple of numpy.ndarray, numpy.ndarray, numpy.ndarray, \ numpy.ndarray, numpy.ndarray, numpy.ndarray :param bool no_variation: whether (if True) or not (if False) intra-individual \ variation is set to zero among the activities :return: """ # the amount of minutes in 1 hour HOUR_2_MIN = temporal.HOUR_2_MIN # the activity-related parameters (in hours) start_mean, start_std, end_mean, end_std, dt_mean, dt_std = data # set the standard deviations to zero (time is in hours) if no_variation: start_std[:] = 0 end_std[:] = 0 # since the start time may occur over midnight, express time as [-12, 12) start_mean = mg.from_periodic(start_mean) # for the demographics with a "work" or "school" occupation # set the sleep end time to the breakfast start time if self.demographic in [dmg.ADULT_WORK, dmg.CHILD_SCHOOL]: # breakfast start time in HOURS [0, 24) bf_start = np.array([x.t_start for x in self.params.breakfasts]) / HOUR_2_MIN # sleep end time is the breakfast start time # make sure time is in [0, 24) format end_mean = bf_start # set the mean start time (in minutes) self.params.sleep_start_mean = mg.hours_to_minutes(start_mean) # set the standard deviation of start time (in minutes) self.params.sleep_start_std = mg.hours_to_minutes(start_std) # set the mean end time (in minutes) self.params.sleep_end_mean = mg.hours_to_minutes(end_mean) # set the standard deviation of end time (in mintues) self.params.sleep_end_std = mg.hours_to_minutes(end_std) return
def initialize(self): """ This function sets up the trial #. gets the CHAD data for sleep under the appropriate conditions for means and standard deviations \ for both sleep duration and sleep start time #. gets N samples the CHAD data for sleep duration and sleep start time for the N trials #. updates the :attr:`params` to reflect the newly assigned sleep parameters for the simulation :return: """ # get the appropriate parameters per person in the household keys = [mg.KEY_SLEEP] # obtain the CHAD parameters relevant to sleeping for each person in the household y = super(Sleep_Trial, self).initialize(keys) # the mean and standard deviations of the start time, end time, and duration # for sleeping start_mean, start_std, end_mean, end_std, dt_mean, dt_std = y[ mg.KEY_SLEEP] # Need to convert the start time from at [-12, 12) hours format to a [0, 24) hours format # for mean start time and end time start_mean = mg.from_periodic(start_mean) end_mean = mg.from_periodic(end_mean) # set the standard deviations to zero [time in hours] start_std[:] = 0 end_std[:] = 0 # adjust the key-word arguments to take account to sleep information self.adjust_params(start_mean=start_mean, start_std=start_std, end_mean=end_mean, end_std=end_std) return
def periodicity_CHADID(df): """ This function combines entries for sleep with the periodicity assumption for a \ given day (CHADID). If there are two events starting at 0:00 and ending in the morning AND \ another event starting in the evening and ending at 0:00 on the SAME DAY, \ we combine the two events into one event. We assume that the person goes to sleep \ on the same start time and wakes up at the same time (periodicity assumption). :param pandas.core.frame.DataFrame df: sleep events for 1 CHADID :return: return sleep data with the periodicity assumption for 1 CHADID :rtype: pandas.core.frame.DataFrame """ # create an empty list df_list = list() # if the list contains only 1 or 0 entries if (len(df) <= 1): result = pd.DataFrame(df)[chad.EVENTS_COLNAMES] else: # store the activity act = [df.iloc[0].act] # store the data date = [df.iloc[0].date] # store the CHADID chadid = [df.iloc[0].CHADID] # store the PID pid = [df.iloc[0].PID] # for each entry for i in range(len(df)): # store the start time start = df.iloc[i].start # if the current entry does not end with 0, keep the entry if df.iloc[i].end != 0: end = df.iloc[i].end else: # if the entry ends with zero, take the value of the first entry end = df.iloc[0].end # calculate the duration dt = [mg.from_periodic(end - start, do_hours=True)] # set the start and end time for entry into dataframe start = [start] end = [end] # create dictionary for the new entry d = {'CHADID': chadid, 'PID': pid, 'start': start, 'end': end, 'dt': dt, \ 'act': act, 'date': date} # add the entry to the list df_list.append(pd.DataFrame(d)) # if the entry includes the periodicity assumption, throw away the top entry if not (df.iloc[i].end != 0): df_list.pop(0) # store the results as a dataframe result = pd.concat(df_list)[chad.EVENTS_COLNAMES] return result
def get_current_meal(self, time_of_day): """ This function gets the closest meal to the time of day. :param int time_of_day: the time of day :return: return the meal :rtype: meal.Meal """ DAY_2_MIN = temporal.DAY_2_MIN # the number of meals N = self.num_meals # an array where the True values shows the index of the current meal idx = np.zeros(N, dtype=bool) # loop through each meal for q in range(N): # get the index for the next meal i = self.meals[q].id j = (i + 1) % N k = (i - 1) % N # store the time of day , current meal, next meal, and meal after next the start time t, ti, tj, tk = time_of_day, self.meals[i].t_start, self.meals[ j].t_start, self.meals[k].t_start # meal time is from the start time until the midpoint between the two meals # ex: t_max(bf) = t_start(bf) + ( t_start(lunch) - t_start(bf) ) / 2 # t_min(bf) = t_start(dinner) + ( t_start(bf) - t_start(dinner) ) /2 # doing math around zero. if (tj < ti): # change time to periodic time [-DAY_2_MIN / 2, DAY_2_MIN) tj = mg.to_periodic(tj, do_hours=False) ti = mg.to_periodic(ti, do_hours=False) # take the average top = np.floor((ti + tj) / 2).astype(int) # convert to normal time [0, DAY_2_MIN) top = mg.from_periodic(top, do_hours=False) else: top = np.floor((ti + tj) / 2).astype(int) # do math around zero if (tk > ti): # change time to periodic time [-DAY_2_MIN / 2, DAY_2_MIN) ti = mg.to_periodic(ti, do_hours=False) tk = mg.to_periodic(tk, do_hours=False) # take the average bot = np.floor((tk + ti) / 2).astype(int) # convert to normal time [0, DAY_2_MIN) bot = mg.from_periodic(bot, do_hours=False) else: bot = np.floor((tk + ti) / 2).astype(int) dt_max = (top - bot) % DAY_2_MIN dt0 = (t - bot) % DAY_2_MIN dt1 = (top - t) % DAY_2_MIN idx[i] = (dt0 <= dt_max) and (dt1 < dt_max) and (dt1 > 0) # the current index if idx.any(): ii = np.where(idx == True)[0][0] the_meal = self.meals[ii] else: the_meal = None return the_meal