# API Documentation¶

## Model class¶

class calliope.Model(config_run=None, override=None, initialize_config_only=False)[source]

Calliope model.

Parameters: config_run : str or AttrDict, default None Path to YAML file with run settings, or AttrDict containing run settings. If not given, the included default run and model settings are used. override : AttrDict, default None Provide any additional options or override options from config_run by passing an AttrDict of the form {'model_settings': 'foo.yaml'}. Any option possible in run.yaml can be specified in the dict, inluding override. options. initialize_config_only : bool, default False If True, the model will not be runnable, and only the basic model configuration will be initialized, but time series data will be read or initialized, which can be useful for faster debugging or processing the configuration.
generate_model(t_start=None)[source]

Generate the model and store it under the property m.

Args:
t_start : if self.mode == ‘operate’, this must be specified, but that is done automatically via solve_iterative() when calling run()
get_capacity_factor()[source]

Get capacity factor.

NB: Only production, not consumption, is used in calculations.

get_costs(t_subset=None)[source]

Get costs.

get_eff_ref(var, y, x=None)[source]

Get reference efficiency, falling back to efficiency if no reference efficiency has been set.

get_group_members(group, in_model=True, head_nodes_only=True, expand_transmission=True)[source]

Return the member technologies of a group. If in_model is True, only technologies (head nodes) in use in the current model are returned.

Returns:
• A list of group members if there are any.
• If a group has no members (is only member of other groups, i.e. a head node), a list with a single item containing only the group/technology itself.
• An empty list if the group is defined but not allowed in the current model.
• None if the group doesn’t exist.

Other arguments:

head_nodes_only : if True, don’t return intermediate
groups, i.e. technology definitions that are inherited from. Setting this to False only makes sense if in_model is also False, because in_model=True implies that only head nodes are returned.
expand_transmission : if True, return in-model
transmission technologies in the form tech:location.
get_levelized_cost()[source]

Get levelized costs.

NB: Only production, not consumption, is used in calculations.

get_node_parameters(built_only=False)[source]

If built_only is True, disregard locations where e_cap==0

get_option(option, x=None, default=None, ignore_inheritance=False)[source]

Retrieves options from model settings for the given tech, falling back to the default if the option is not defined for the tech.

If x is given, will attempt to use location-specific override from the location matrix first before falling back to model-wide settings.

If default is given, it is used as a fallback if no default value can be found in the regular inheritance chain. If default is None and the regular inheritance chain defines no default, an error is raised.

If ignore_inheritance is True, the default is immediately used instead of a search through the inheritance chain if the option has not been set for the given tech.

If the first segment of the option contains ‘:’, it will be interpreted as implicit tech subsetting: e.g. asking for ‘hvac:r1’ implicitly uses ‘hvac:r1’ with the parent ‘hvac’, even if that has not been defined, to search the option inheritance chain.

Examples:

• model.get_option('ccgt.costs.om_var')
• model.get_option('csp.weight')
• model.get_option('csp.r', x='33')
• model.get_option('ccgt.costs.om_var',          default='defaults.costs.om_var')
get_parent(y)[source]

Returns the abstract base technology from which y descends.

get_timeres(verify=False)[source]

Returns resolution of data in hours. Needs a properly formatted set_t.csv file to work.

If verify=True, verifies that the entire file is at the same resolution. model.get_timeres(verify=True) can be called after Model initialization to verify this.

get_totals(t_subset=None)[source]

Get total produced and consumed per technology and location.

get_var(var, dims=None)[source]

Return output for variable var as a series, dataframe or panel

If t is one of the variable’s dimensions, Panels and Panel4Ds are transposed such that t is in the major_axis.

Args:

var : variable name as string, e.g. ‘es_prod’

dims : list of indices as strings, e.g. (‘y’, ‘x’, ‘t’); if not given, they are auto-detected

initialize_time()[source]

Performs time resolution reduction, if set up in configuration

ischild(y, of)[source]

Returns True if y is a child of of, else False

load_results()[source]

Load results into model instance for access via model variables.

prev(t)[source]

Using the timesteps set of this model instance, return t-1, even if the set is not continuous.

E.g., if t is [0, 1, 2, 6, 7, 8], model.prev(6) will return 2.

read_data()[source]

Read parameter data from CSV files, if needed. Data that may be defined in CSV files is read before generate_model() so that it only has to be read from disk once, even if generate_model() is repeatedly called.

Note on indexing: if subset_t is set, a subset of the data is selected, and all data including their indices are subsetted. d._dt.index maps a simple [0, data length] index to the actual t index used.

Data is stored in the self.data for each param and technology y: self.data[param][y]

run(iterative_warmstart=True)[source]

Instantiate and solve the model

save_solution(how)[source]

Save model solution. how can be ‘hdf’ or ‘csv’

CSV is supported for legacy purposes but usually, the HDF option should be used.

scale_to_peak(df, peak, scale_time_res=True)[source]

Returns the given dataframe scaled to the given peak value.

If scale_time_res is True, the peak is multiplied by the model’s time resolution. Set it to False to scale things like efficiencies.

set_option(option, value, x=None)[source]

Set option to value. Returns None on success.

A default can be set by passing an option like defaults.constraints.e_eff.

solve(warmstart=False)[source]
Args:
warmstart : (default False) re-solve an updated model
instance

Returns: None

solve_iterative(iterative_warmstart=True)[source]

Solve iterative by updating model parameters.

By default, on optimizations subsequent to the first one, warmstart is used to speed up the model generation process.

Returns None on success, storing results under self.solution

## Constraints¶

calliope.constraints.objective.objective_cost_minimization(model)[source]

Minimizes total system monetary cost. Used as a default if a model does not specify another objective.

calliope.constraints.base.node_constraints_build(model)[source]

Defines variables:

• s_cap: installed storage capacity
• r_cap: installed resource <-> storage conversion capacity
• e_cap: installed storage <-> grid conversion capacity (gross)
• e_cap_net: installed storage <-> grid conversion capacity (net)
• rb_cap: installed secondary resource conversion capacity
calliope.constraints.base.node_constraints_transmission(model)[source]

Constrains e_cap symmetrically for transmission nodes.

calliope.constraints.base.node_costs(model)[source]

Defines variables:

• cost: total costs
• cost_con: construction costs
• cost_op_fixed: fixed operation costs
• cost_op_var: variable operation costs
• cost_op_fuel: primary resource fuel costs
• cost_op_rb: secondary resource fuel costs
calliope.constraints.base.node_energy_balance(model)[source]

Defines variables:

• s: storage level
• es_prod: storage -> carrier (+ production)
• es_con: storage <- carrier (- consumption)
calliope.constraints.base.node_parasitics(model)[source]

Additional variables and constraints for plants with internal parasitics.

Defines variables:

• ec_prod: storage -> carrier after parasitics (+ production)
• ec_con: storage <- carrier after parasitics (- consumption)
calliope.constraints.base.node_resource(model)[source]

Defines variables:

• rs: resource <-> storage (+ production, - consumption)
• r_area: resource collector area
• rbs: secondary resource -> storage (+ production)
calliope.constraints.planning.node_constraints_build_total(model)[source]
calliope.constraints.planning.system_margin(model)[source]
calliope.constraints.optional.group_fraction(model)[source]

Constrain groups of technologies to reach given fractions of e_prod.

calliope.constraints.optional.ramping_rate(model)[source]

Ramping rate constraints.

Depends on: node_energy_balance, node_constraints_build

## Time resolution¶

class calliope.time_tools.TimeSummarizer[source]

Provides methods to reduce time resolution for the given model data.

dynamic_timestepper(data, series)[source]

series must be a series with the same length as the given data.

For each timestep, the series can either be 0 (no adjustment), >0 (marks the first timestep to be compressed, with the integer value giving the number of timesteps to compress) or -1 (marks timesteps that will be dropped or compressed).

For example, series could contain:

[0, 0, 0, 3, -1, -1, 0, 0, 2, -1, 2, -1]


This would result in data with the following new timestep resolution:

[1, 1, 1, 3, 1, 1, 2, 2]


Warning: modifies the passed data object in-place. Returns None on success.

reduce_resolution(data, resolution)[source]

Reduces the resolution of the entire data to resolution, which must be an integer and greater than the initial resolution.

Modifies the passed data object in-place and returns None.

calliope.time_tools.masks_to_resolution_series(masks, how='or', resolution=None, drop_with_padding=None)[source]

Converts a list of overlapping masks into a series of time step resolutions.

Parameters: how : str, default ‘or’ or or and. resolution : int, default None If given, will break up masked areas into timesteps of at most the given length (with possibly a over timestep at a lower length at the end of the masked area). If None, all contingent masked areas become single timesteps. drop_with_padding : int, default None If given, all masked areas are dropped, except for a padding area around the retained high-resolution areas. The padding is determined by drop_with_padding * resolution, so if drop_with padding is 1 and resolution is 24, a single 24-hour timestep each will be kept before and after each high-resolution area. If set and resolution is None an error is raised, unless set to 0, which will drop all non-masked areas without padding.
calliope.time_tools.resolution_series_to_mask(resolution_series)[source]

Turns a resolution series into a mask.

calliope.time_tools.resolution_series_uniform(data, resolution)[source]

Resolution series to reduce resolution uniformly.

Parameters: data : Calliope model data resolution : int or float Resolution (in hours) to downsample all data to.

calliope.time_masks.mask_extreme(data, tech, var='r', how='max', length=24, locations=None, padding=None)[source]

Mask everywhere except the length where var for the technology tech across the given list of locations is either minmal or maximal.

Parameters: data : Calliope model data tech : str Technology whose var to find extreme for. var : str, default ‘r’ how : str, default ‘max’ ‘max’ or ‘min’ length : int, default 24 Timesteps to mask. locations : list, default None List of locations to use, if None, uses all available locations. padding : int, default None Pad beginning and end of the unmasked area by the number of timesteps given.
calliope.time_masks.mask_extreme_week(data, tech, var='r', how='sum', what='min')[source]

Mask everywhere except the week containing the day where var of tech is minimal (what=’min’) or maximal (what=’max’) across the sum (how=’sum’) of or the mode (most) of locations (how=’mode’).

Parameters: data : Calliope model data tech : str Technology whose var to find extreme week for. var : str, default ‘r’ how : str, default ‘sum’ ‘sum’ or ‘mode’ what : str, default ‘min’ ‘min’ or ‘max’
calliope.time_masks.mask_relative_difference(data, target1, target2, days=5, padding_days=1, per_zone=False)[source]

Masks everywhere except the days number of days where the resource of the two technologies target1 and target2 is most different.

Parameters: data : Calliope model data target1 : str target2 : str days : int, default 5 padding_days : int, default 1 per_zone: bool, default False
calliope.time_masks.mask_zero(data, tech, var='r', locations=None)[source]

Mask where var for the technology tech across the given list of locations is zero.

var defaults to r.

If locations not given, uses all available locations.

calliope.read.read_dir(directory, tables_to_read=None)[source]

Combines output files from directory and return an AttrDict containing them all.

If a solution is missing or there is an error reading it, an empty AttrDict is added to the results in its stead and the error is logged.

calliope.read.read_hdf(hdf_file, tables_to_read=None)[source]

Read model solution from HDF file

## Analyzing results¶

calliope.analysis.areas_below_resolution(solution, resolution)[source]

Returns a list of (start, end) timestamp tuples delimiting those areas in the solution below the given timestep resolution (in hours).

calliope.analysis.get_delivered_cost(solution, cost_class='monetary', carrier='power', count_unmet_demand=False, unit_multiplier=1.0)[source]

Get the levelized cost per unit of energy delivered for the given cost_class and carrier.

Parameters: solution : solution container cost_class : str, default ‘monetary’ carrier : str, default ‘power’ count_unmet_demand : bool, default False Whether to count the cost of unmet demand in the final delivered cost. unit_multiplier : float or int, default 1.0 Adjust unit of the returned cost value. For example, if model units are kW and kWh, unit_multiplier=1.0 will return cost per kWh, and unit_multiplier=0.001 will return cost per MWh.
calliope.analysis.get_domestic_supply_index(solution)[source]

Assuming that solution specifies a domestic cost class to give each technology a domesticity score, return the total domestic supply index for the given solution.

calliope.analysis.get_group_share(solution, techs, group_type='supply', var='e_prod')[source]

From solution.summary, get the share of the given list of techs from the total for the given group_type, for the given var.

calliope.analysis.get_hhi(solution, shares_var='e_cap', exclude_patterns=['unmet_demand'])[source]

Returns the Herfindahl-Hirschmann diversity index.

$$HHI = \sum_{i=1}^{I} p_{i}^2$$

where $$p_{i}$$ is the percentage share of each technology i (0-100).

$$HHI$$ ranges between 0 and 10,000. A value above 1800 is considered a sign of a concentrated market.

calliope.analysis.get_levelized_cost(solution, cost_class='monetary', carrier='power', group=None, locations=None, unit_multiplier=1.0)[source]

Get the levelized cost per unit of energy produced for the given cost_class and carrier, optionally for a subset of technologies given by group and a subset of locations.

Parameters: solution : solution container cost_class : str, default ‘monetary’ carrier : str, default ‘power’ group : str, default None Limit the computation to members of the given group (see the shares table in the solution for valid groups). locations : str or iterable, default None Limit the computation to the given location or locations. unit_multiplier : float or int, default 1.0 Adjust unit of the returned cost value. For example, if model units are kW and kWh, unit_multiplier=1.0 will return cost per kWh, and unit_multiplier=0.001 will return cost per MWh.
calliope.analysis.get_swi(solution, shares_var='e_cap', exclude_patterns=['unmet_demand'])[source]

Returns the Shannon-Wiener diversity index.

$$SWI = -1 \times \sum_{i=1}^{I} p_{i} \times \ln(p_{i})$$

where where I is the number of categories and $$p_{i}$$ is each category’s share of the total (between 0 and 1).

$$SWI$$ is zero when there is perfect concentration.

calliope.analysis.get_unmet_demand_hours(solution, carrier='power', details=False)[source]

Get information about unmet demand from solution.

Parameters: solution : solution container carrier : str, default ‘power’ details : bool, default False By default, only the number of hours with unmet are returned. If details is True, a dict with ‘hours’, ‘timesteps’, and ‘dates’ keys is returned instead.
calliope.analysis.map_results(results, func, as_frame=False)[source]

Applies func to each model solution in results, returning a pandas DataFrame (if as_frame is True) or Series, indexed by the run names (if available).

calliope.analysis.plot_carrier_production(solution, carrier='power', subset_t=None, **kwargs)[source]

Generate a stackplot of the production by the given carrier.

Parameters: solution : solution container carrier : str, default ‘power’ subset_t : 2-tuple of str or None, default None Specify a date subset for which to plot, for example, (‘2005-02-01’, ‘2005-02-10’) , or (‘2005-02-01’, None) **kwargs : passed to plot_timeseries (see its documentation)
calliope.analysis.plot_installed_capacities(solution, types=['supply', 'conversion', 'storage'], unit_multiplier=1.0, unit_label='kW', **kwargs)[source]

Plot installed capacities (e_cap) with a bar plot.

Parameters: types : list, default [‘supply’, ‘conversion’, ‘storage’] Technology types to include in the plot. unit_multiplier : float or int, default 1.0 Multiply installed capacities by this value for plotting. unit_label : str, default ‘kW’ Label for capacity values, adjust this when changing unit_multiplier. **kwargs : are passed to pandas.DataFrame.plot()
calliope.analysis.plot_timeseries(solution, data, carrier='power', demand='demand_power', types=['supply', 'conversion', 'storage', 'unmet_demand'], colormap=None, ticks=None, resample=None)[source]

Generate a stackplot of the data for the given carrier, plotting the demand on top.

Use plot_carrier_production for a simpler way to plot production by a given carrier.

Parameters: solution : solution container data : pandas DataFrame subset of solution to plot carrier : str, default ‘power’ name of the carrier to plot demand : str, default ‘demand_power’ name of a demand tech whose time series to plot on top types : list, default [‘supply’, ‘conversion’, ‘storage’, ‘unmet_demand’] Technology types to include in the plot. colormap : matplotlib colormap Colormap to use, if not given, the colors specified for each technology in the solution’s metadata are used. ticks : str, default None Where to draw x-axis (time axis) ticks. By default (None), auto-detects, but can manually set to either ‘hourly’, ‘daily’, or ‘monthly’. resample : dict, default None Give options for pandas.DataFrame.resample in a dict, to resample the entire time series prior to plotting.
calliope.analysis.plot_transmission(solution, tech='hvac', carrier='power', labels='utilization', figsize=(15, 15), fontsize=9, show_scale=True, ax=None)[source]

Plot transmission links on a map. Requires that model metadata have been defined with a lat/lon for each model location and a boundary for the map display.

Requires Basemap and NetworkX to be installed.

Parameters: solution : solution container tech : str, default ‘hvac’ Which transmission technology to plot. carrier : str, default ‘power’ Which carrier to plot transmission for. labels : str, default ‘utilization’ Determines how transmission links are labeled, either transmission or utilization. figsize : (int, int), default (15, 15) Size of resulting figure. fontsize : int, default 9 Font size of figure labels. show_scale : bool, default True Plot a distance scale on the map. ax : matplotlib axes, default None

## Utility classes: AttrDict, Parallelizer, Exceptions¶

class calliope.utils.AttrDict(source_dict=None)[source]

A subclass of dict with key access by attributes:

d = AttrDict({'a': 1, 'b': 2})
d.a == 1  # True


Includes a range of additional methods to read and write to YAML, and to deal with nested keys.

as_dict(flat=False)[source]

Return the AttrDict as a pure dict (with nested dicts if necessary).

copy()[source]

Override copy method so that it returns an AttrDict

del_key(key)[source]

Delete the given key. Properly deals with nested keys.

classmethod from_yaml(f, resolve_imports=True)[source]

Returns an AttrDict initialized from the given path or file object f, which must point to a YAML file.

If resolve_imports is True, import: statements are resolved recursively, else they are treated like any other key.

When resolving import statements, anything defined locally overrides definitions in the imported file.

classmethod from_yaml_string(string)[source]

Returns an AttrDict initialized from the given string, which must be valid YAML.

get_key(key, default=MISSING)[source]

Looks up the given key. Like set_key(), deals with nested keys.

If default is anything but _MISSING, the given default is returned if the key does not exist.

init_from_dict(d)[source]

Initialize a new AttrDict from the given dict. Handles any nested dicts by turning them into AttrDicts too:

d = AttrDict({'a': 1, 'b': {'x': 1, 'y': 2}})
d.b.x == 1  # True

keys_nested(subkeys_as='list')[source]

Returns all keys in the AttrDict, sorted, including the keys of nested subdicts (which may be either regular dicts or AttrDicts).

If subkeys_as='list' (default), then a list of all keys is returned, in the form ['a', 'b.b1', 'b.b2'].

If subkeys_as='dict', a list containing keys and dicts of subkeys is returned, in the form ['a', {'b': ['b1', 'b2']}].

set_key(key, value)[source]

Set the given key to the given value. Handles nested keys, e.g.:

d = AttrDict()
d.set_key('foo.bar', 1)
d.foo.bar == 1  # True

to_yaml(path=None, convert_objects=True, **kwargs)[source]

Saves the AttrDict to the given path as a YAML file.

If path is None, returns the YAML string instead.

Any additional keyword arguments are passed to the YAML writer, so can use e.g. indent=4 to override the default of 2.

convert_objects (defaults to True) controls whether Numpy objects should be converted to regular Python objects, so that they are properly displayed in the resulting YAML output.

union(other, allow_override=False, allow_replacement=False)[source]

Merges the AttrDict in-place with the passed other AttrDict. Keys in other take precedence, and nested keys are properly handled.

If allow_override is False, a KeyError is raised if other tries to redefine an already defined key.

If allow_replacement, allow “_REPLACE_” key to replace an entire sub-dict.

class calliope.Parallelizer(target_dir, config_run=None)[source]

Arguments:

• target_dir: path to output directory for parallel runs.
• config_run: path to YAML file with run settings. If not given, the included example run.yaml is used.
exception calliope.exceptions.ModelError[source]

ModelErrors should stop execution of the model, e.g. due to a problem with the model formulation or input data.

exception calliope.exceptions.ModelWarning[source]

ModelWarnings should be raised for possible model errors, but where execution can still continue.

Previous: Development guide | Next: Release History