Abstract simulators

Base simulators

The following simulators are abstract simulators that serve as basis for new implementations of simulation.

class demod.simulators.base_simulators.Simulator(n_households, logger=None)

Abstract mother class for all the simulators.

The 3 methods of this simulator are meant to be called by its children. See Creating your first simulator for more informations.

n_households

The number of households simulated.

Type

int

current_time_step

The current time step of the simulation.

Type

int

logger

A logger object, that can log the value of variables during the simulation.

Type

demod.simulators.base_simulators.SimLogger

__init__(n_households, logger=None)

Initialize the simulator.

This method is supposed to be called in the __init__() of all children of Simulator .

Parameters
Raises
  • TypeError – If the type of n_housholds is not an integer

  • ValueError – If n_households is non positive

Return type

None

initialize_starting_state(start_time_step=0, *args, **kwargs)

Initialize the values of the variables.

If a start_time_step is given, the initilization will call the step function to simulate the requested number of time steps. Any arguments to be used by the step function can be passed as *args, **kwargs.

Parameters

start_time_step (int) – The time step at which the simulation should start. Defaults to 0.

Raises
  • TypeError – If the type of start_time_step is not int.

  • ValueError – If the start_time_step is negative.

Return type

None

step()

Perform a simulation step.

Increment the current_time_step, calls logger, and clear cached variables.

Return type

None

class demod.simulators.base_simulators.MultiSimulator(simulators, logger=None)

Abstract simulator that can handles multiple sub-simulators.

It distributes the simulation instructions to the subsimulators and handles reconstructing the output variables. Subsimulators can be any children of Simulator, and should ideally be of the same kind, to allow getter methods to work correctly.

simulators

sub-simulators of the multi-simulator.

Type

List[demod.simulators.base_simulators.Simulator]

step(*args, **kwargs)

Step function for the multi simulator.

It handles the different *args and **kwargs by redistributing them to the inside simulators.

Note

A future implmentation could implement parallelization.

Return type

None

get_mask_subgroup(subgroup)

Return a mask of the households from the subgroup.

Parameters

subgroup – dictonary for the requuested subgroup of households

Returns

The mask, where households corresponding to subgroup

(false if not in subgroup, true if in subgroup)

initialize_starting_state(start_time_step=0, *args, **kwargs)

Initialize the values of the variables.

If a start_time_step is given, the initilization will call the step function to simulate the requested number of time steps. Any arguments to be used by the step function can be passed as *args, **kwargs.

Parameters

start_time_step (int) – The time step at which the simulation should start. Defaults to 0.

Raises
  • TypeError – If the type of start_time_step is not int.

  • ValueError – If the start_time_step is negative.

Return type

None

class demod.simulators.base_simulators.TimeAwareSimulator(n_households, start_datetime=datetime.datetime(2014, 1, 1, 4, 0), step_size=datetime.timedelta(seconds=60), logger=None, **kwargs)

Time aware simulator remembers the time during the simulation.

This simulator provides an initialization methods that computes how many steps are required to get the the start of the simulation. For example, this is useful when a simulator is initialized for 4 am but should start at 6:30 am. The step function keeps track of the time.

current_time

The current time of the simulation.

Type

datetime.datetime

step_size

The step size of the simulation.

Type

datetime.timedelta

initialize_starting_state(*args, initialization_time=None, **kwargs)

Initialize the starting state of a time aware simulator.

This method will compute how many initialization steps are required to get to current_time. The steps are calculated based on step_size and initialization_time. The initial datetime will be current_time or if it is not possible due to step_size constraints, the first datetime reachable by the simulator before current_time.

Parameters
  • *args – Any arg that must be passed to the step method during the initialization.

  • initialization_time (Optional[Union[datetime.datetime, datetime.timedelta]]) – The time or datetime for which the simulator is initalized. Defaults to None (no initialization steps, initialized at the current datetime).

  • *kwargs – Any keyword arg that must be passed to the step method during the initialization.

Raises
  • ValueError – If the initialization_time is not reachable by the simulator.

  • NotImplementedError – If the type of the initialization_time is not recognized.

Return type

None

step()

Perform a time aware step.

Update the current_time according to the step_size.

Return type

None

on_before_next_day()

Call back when current time passes a new day.

This function is called by the corresponding set callback decorator method: Callbacks.before_next_day().

Return type

None

on_before_next_day_4am()

Call back when current time passes a new day.

This function is called by the corresponding set callback decorator method: Callbacks.before_next_day_4am().

Return type

None

on_after_next_day()

Call back when current time passes a new day.

This function is called by the corresponding set callback decorator method: Callbacks.after_next_day().

Return type

None

on_after_next_day_4am()

Call back when current time passes a new day.

This function is called by the corresponding set callback decorator method: Callbacks.after_next_day_4am().

Return type

None

on_before_refresh_time()

Call back when current time passes the refresh time form data.

This function is called by the corresponding set callback decorator method: Callbacks.before_refresh_time().

Return type

None

on_after_refresh_time()

Call back when current time passes the refresh time form data.

This function is called by the corresponding set callback decorator method: Callbacks.after_refresh_time().

Return type

None

Callbacks for TimeAwareSimulator

class demod.simulators.base_simulators.Callbacks

Defines different Callbacks for TimeAwareSimulator children.

Callbacks are decorators for the step functions. Each callback will call a specific method from the class which has its step function decorated. See below the function called by each callbacks, and when it is called.

Usage:

You need to decorate the step method of your class. Example:

@ Callbacks.desired_callback
def step(self, *args, **kwargs):
    # ... your code ...
    super().step()
static before_refresh_time(step_method)

Set a call back before the .data.refresh_time, calling ‘self.on_before_refresh_time()’

Parameters

step_method (Callable[[..], None]) – the step method to decorate.

Return type

Callable[[..], None]

static after_refresh_time(step_method)

Set a call back after the .data.refresh_time, calling ‘self.on_after_refresh_time()’

Parameters

step_method (Callable[[..], None]) – the step method to decorate.

Return type

Callable[[..], None]

static before_next_day(step_method)

Set a call back before the next day, calling ‘self.on_before_next_day()’

Parameters

step_method (Callable[[..], None]) – the step method to decorate.

Return type

Callable[[..], None]

static after_next_day(step_method)

Set a call back after the next day, calling ‘self.on_after_next_day()’

Parameters

step_method (Callable[[..], None]) – the step method to decorate.

Return type

Callable[[..], None]

static before_next_day_4am(step_method)

Set a call back before the next day at 4 am, calling ‘self.on_before_next_day_4am()’

Parameters

step_method (Callable[[..], None]) – the step method to decorate.

Return type

Callable[[..], None]

static after_next_day_4am(step_method)

Set a call back after the next day at 4 am, calling ‘self.on_after_next_day_4am()’

Parameters

step_method (Callable[[..], None]) – the step method to decorate.

Return type

Callable[[..], None]

Component simulators

The following abstract simulators are dedicated to specific components. Specific components are for example: activity of the residents, weather or appliance consumption.

Activity

class demod.simulators.activity_simulators.ActivitySimulator(n_households, logger=None)

Base simulator for the activity.

Simply provides GetMethod’s useful for all simulators.

activity_labels

A list containing the label of the available activites.

Type

List[Any]

get_occupancy()

Return the number of occupants in the households.

Occupants means that the person is in the house.

Return type

numpy.array

get_active_occupancy()

Return the number of active occupants in the households.

Active occupant means that the person is in the house and that this person is active. A person is active if not inactive(sleeping or sick).

Return type

numpy.array

get_performing_activity(activity_name)

Return the number of occupants doing activity_name.

If the given activity_name corresponds to an activity in activity_labels.

Parameters

activity_name (str) – The desired activity.

Return type

numpy.array

States

These simulators keeps track of the activity in households as being in a state. At each step, a change of states is sampled for all households using Monte Carlo sampling.

class demod.simulators.activity_simulators.MarkovChain1rstOrder(n_households, n_states, transition_prob_matrices, labels=None, **kwargs)

Base simulator for the activity of households.

Implements a 1^{rst} order Markov chain. The simulator iterates over the transition_prob_matrices.

n_states

The number of states availables.

Type

int

current_states

The current states at which the households are.

Type

numpy.ndarray

initialize_starting_state(starting_state_pdf, start_time_step=0, checkcdf=True)

Initialize the starting states of the households.

Parameters
  • starting_state_pdf (numpy.ndarray) –

    An array containing the pdf for each of the state at the

    time 0.

  • checkcdf (bool) – optional. Will check if teh transition_prob_matrices have correct values using the check_valid_cdf() function

  • start_time_step (int) –

Raises

AssertionError – If the parameters have wrong types or shapes

Return type

None

step()

Perfom a step Markov chain step.

Update the current states using the appropriate value form the Transition Probability matrix.

Return type

None

class demod.simulators.activity_simulators.SemiMarkovSimulator(n_subjects, n_states, transition_prob_matrices, duration_pdfs, labels=None, **kwargs)

Semi Markov chain Simulator.

Similar to a first order Markov Chains, but it also includes the duration of the states. This is sometimes refer to as a 2nd order markov chain.

In the current implementations, the duration matrices can depend on only the new sampled states, or also on the previous state. It would be nice to sample either from duration matrices or from duration fuunctions. (ex Weibul)

The SemiMarkovSimulator is not time-homogeneous, as the probabilities changes with respect to time.

Corresponding data loader: load_tpm_with_duration()

n_subjects

The number of subjects to be simulated.

n_states

The number of states availables.

Type

int

current_states

The current states, array of integers.

Type

numpy.ndarray

initialize_starting_state(starting_state_pdf, starting_durations_pdfs, start_time_step=0, checkcdf=True)

Initialize the starting state.

Parameters
  • starting_state_pdf (numpy.ndarray) – An array containing the pdf for each of the states at the time 0. Shape = (n_states)

  • starting_durations_pdfs (numpy.ndarray) – An array containing the pdf of the times left at the start for each states. Shape = (n_states, n_times)

  • start_time_step (int) – The number of step to perform during intialization.

  • checkcdf (bool) – optional. Will check if the pdfs have correct values using the check_valid_cdf function.

Raises

AssertionError – If the parameters have wrong types or shapes

Return type

None

step()

Perform one step of the SemiMarkov model.

Checks the subjects that require an update. Then it updates the new states of these subjects, and from that it samples the duration of that new state.

Sparse simulators

This implementation provides mainly the same features as states simulators with better performances in the case of large transition probability matrices.

class demod.simulators.sparse_simulators.SparseStatesSimulator(n_households, sparse_tpm, starting_state_pdf, labels=None, time_aware=False, start_datetime=None, use_quarters=False, use_7days=False, use_week_ends_days=True, **kwargs)

States simulator.

Provides the basis for a states simulator that used a sparse implementation.

tpm

The set of TPMs used by the simulator.

Type

demod.utils.sparse.SparseTPM

state_labels

The labels of the states in the TPM.

Type

Union[List[str], List[int], numpy.ndarray]

assign_sparse_tpm_and_labels(sparse_tpm, labels=None)

Assign the TPMs to the simulator.

Parameters
  • sparse_tpm (demod.utils.sparse.SparseTPM) – The set of TPMs to be used by the simulator.

  • labels (Optional[Union[List[str], List[int], numpy.ndarray]]) – The labels of the states in the TPM. Defaults to None.

Raises
  • TypeError – Wrong types in the inputs

  • ValueError – TPM has wrong shape

  • ValueError – Labels have wrong length

Return type

None

get_n_doing_state(state)

Get the number of residents doing the desired state or activity.

Parameters

state (Union[int, str, list]) – the requested state or activity, or the list of the requested states

Raises
  • ValueError – If the given value of input is not valid

  • Exception – If the simulator object has not been initialized with the activity_labels attributes

  • TypeError – If the input state has an undesired type

Returns

The number of occupants performing the activity, or the list of ndarrays if state was given as a list

get_n_doing_activity(activity)

Return the number of residents doing the desired activity.

Parameters

activity (str) –

initialize_starting_state(starting_state_pdf, start_time_step=0, checkcdf=True)

Initialize the starting state.

Performs some steps to reach start_time_step.

Parameters
  • starting_state_pdf – numpy.ndarray An array containing the pdf for each of the state at the time 0.

  • checkcdf – bool optional. Will check if teh transition_matrices have correct values using the check_valid_cdf function

Raises

AssertionError – If the parameters have wrong types or shapes

step(increment=datetime.timedelta(seconds=600))

Perform a simulation step.

Increment the current_time_step, calls logger, and clear cached variables.

Appliances

class demod.simulators.appliance_simulators.AppliancesSimulator(n_households, appliances_dict, equipped_sampling_algo='basic', equipped_set_defined=None, real_profiles_algo='nothing', **kwargs)

Class for Simulating appliances usage.

This class is abstract but provides an interface for simulating step based appliances.

Appliances informations are stored in self.appliance which is the appliance_dict. The states an information of all appliances are stored as different numpy arrays of shape = (n_households, n_appliances). The attributes below show more in dept which information are stored.

A state based appliance works with ON/OFF states.

  1. It is switched ON by the simulator at step $n$.

  2. The switch-ON event samples for how long the appliance will be ON, ($m$ steps).

  3. The appliance is switched-OFF at step $n+m$.

The consumption load of appliances can be either constant or either variable.

constant

a single value of consumption is assigned

variable

the consumption changes each step based on a real load profile from load_real_profiles_dict()

random

FOR FUTURE IMPLEMENTATION. The load fluctuates over a mean value, or using a random distribution.

Step based appliances have a number of steps that they are activated before they stop. The number of steps can be

constant

using a mean duration

variable

in case of a real load profile, it is its duration

random

follow a distribution

infinite

some appliances that are always ON

activity related

FOR FUTURE IMPLEMENTATION. The duration is sample based on durations obtained for TOU statistics.

Appliances also have a stand-by consumption for when they are OFF.

The consumption of appliances can be electricity, DHW (domestic hot water), or gaz.

n_steps_left

An array of size = (n_households, n_appliances) that stores the duration of the current use. When n_steps_left == 0, the appliance is switched OFF.

Type

numpy.ndarray

n_steps_till_refresh

An array of size = (n_households, n_appliances). Tracks how many steps are left before the appliance can be switched ON again.

available_appliances

An array of boolean of size = (n_households, n_appliances), where the element [i, j] is True if the i-est households owns the j-est appliance else False.

Type

numpy.ndarray

appliances

An appliances_dict containing the information for each of the n_appliances. Each key is a different appliance.

Type

Dict[str, numpy.ndarray]

load_duration

An array of size = (n_households, n_appliances) where values correspond to how long the corresponding load pattern lasts.

Type

numpy.ndarray

initialize_starting_state(*args, **kwargs)

Initialize the starting states of the appliances.

Calls as well the parents methods for initialization, passing args and kwargs.

The state of the appliances must be initialized here. The current implementation makes every appliance being turned off.

TODO: FOR FUTURE IMPLEMENTATION find a way to randomly sample which appliance is on.

sample_available_appliances(equipped_sampling_algo='basic', equipped_set_defined=None, **kwargs)

Initialize which appliances are available in the households.

Parameters
  • equipped_sampling_algo (str) –

    The method used for sampling. Available:

    basic

    uses a monte carlo sampling from appliances[‘equipped_dwellings_probs’]

    subgroup

    like basic sampling but uses self.data.load_subgroup_ownership_pdf()

    correlated

    check which appliances are usually coming together. FOR FUTURE IMPLEMENTATION

    set_defined

    matches the requested set for each household given as appliance_set.

    all

    give all appliances to every households

  • equipped_set_defined (Optional[dict]) –

Raises

ValueError – For unknown equipped_sampling_algo

Returns

available_appliances, a boolean array of size size = (n_household, n_appliances) where True means the appliance is available and False that it is not.

Return type

numpy.ndarray

sample_real_load_profiles(real_profiles_algo='nothing')

Assign a load profile for each appliance.

Uses load_real_profiles_dict() to get real load profiles for the appliances.

Samples the load profiles of each appliance based on the real_profiles_algo value. Note that the appliance types that do not have real load profiles will have constant loads. Splits the appliances related activity if the related activity is occuring the whole day (ex. ‘level’ activity for fridges). These appliances will run for the full days, repeating their profiles.

Parameters

real_profiles_algo (str) –

the method used to sample the real profiles currently implemented

nothing

does not use the real load profiles

only_always_on

samples just the profiles of appliances that are always activated (ex. fridges and freezers)

only_switched_on

Samples only the load profiles for appliances when they are switched ON. (use cycle)

uniform

sample uniformly by attributing randomly a profiles from the corresponding appliance_type

Return type

numpy.ndarray

switch_on(indexes_household, indexes_appliance)

Switches on appliances at the given indices.

Depending on the type of the appliances switch-on events are differents. In particular we distinguish between:

constant load

appliances consumes the same all the time

load pattern based

appliances has a specific load profile

varying duration

the use duration varies stochastically based on sample_durations()

Parameters
  • indexes_household – the index of the household.

  • indexes_appliance – the index of the appliances, matching with the households

switch_off_inactive(active_occupancy)

Switch off the appliances that are unused due to activity.

step()

Update appliances states.

It simply updates the appliances times left, and call the parent method to update steps variables.

Implementation in children should control when to call switch ON and switch OFF events, and call this step method by using super().step().

Return type

None

update_iteration_variables()

Update the incremental variables.

Return type

None

sample_durations(indexes_household, indexes_appliance)

Sample the duration of a load.

TODO: FOR FUTURE IMPLEMENTATION implement varying durations for all appliances types

get_power_demand()

Return the power consumption of the household.

get_thermal_gains()

Return the thermal gains from the appliances.