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.
-
__init__
(n_households, logger=None)¶ Initialize the simulator.
This method is supposed to be called in the
__init__()
of all children ofSimulator
.- Parameters
n_households (int) –
logger (Optional[demod.simulators.base_simulators.SimLogger]) –
- 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
, callslogger
, 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
-
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 onstep_size
andinitialization_time
. The initial datetime will becurrent_time
or if it is not possible due to step_size constraints, the first datetime reachable by the simulator beforecurrent_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 thestep_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 inactivity_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()
functionstart_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.
-
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
attributesTypeError – 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
, callslogger
, 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.
It is switched ON by the simulator at step $n$.
The switch-ON event samples for how long the appliance will be ON, ($m$ steps).
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.