urbs.py module description

Overview

The following is a minimum “hello world” script that shows the life cycle of the optimization object prob, and how the various urbs module functions create it, modify it and process it.:

import urbs
from pyomo.opt.base import SolverFactory

# read input, create optimisation problem
data = urbs.read_excel('mimo-example.xlsx')
prob = urbs.create_model(data)

# solve problem, read results
optim = SolverFactory('glpk')
result = optim.solve(prob)
prob.solutions.load_from(result)

# save problem instance (incl. input and result) for later analyses
urbs.save(prob, 'mimo-example.pgz')

# write report and plot timeseries
urbs.report(prob, 'report.xlsx')
urbs.plot(prob, 'Elec', 'Mid')

The following lists and describes the use of all module-level functions. They are roughly ordered from high-level to low-level access, followed by helper functions.

Create model

urbs.read_excel(filename)
Parameters:filename (str) – spreadsheet filename
Returns:urbs input dict

The spreadsheet must contain 7 sheets labelled ‘Commodity’, ‘Process’, ‘Process-Commodity’, ‘Transmission’, ‘Storage’, ‘Demand’ and ‘SupIm’. It can contain 2 additional sheets called ‘Buy-Sell-Price’ and ‘Hacks’. If present, function add_hacks() is called by create_model() upon model creation.

Refer to the mimo-example.xlsx file for exemplary documentation of the table contents and definitions of all attributes by selecting the column titles.

urbs.create_model(data, timesteps)

Returns a Pyomo ConcreteModel object.

Parameters:
  • data (dict) – input like created by read_excel()
  • timesteps (list) – consecutive list of modelled timesteps
Returns:

urbs model object

Timestep numbers must match those of the demand and supim timeseries.

If argument data has the key 'hacks', function add_hacks() is called with data['hacks'] as the second argument.

urbs.add_hacks(model, hacks)

Is called by create_model() to add special elements, e.g. constraints, to the model. Each hack, if present, can trigger the creation of additional sets, parameters, variables or constraints. Refer to the code of this function to see which hacks exists and what they do.

As of v0.3, only one hack exists: if a line “Global CO2 limit” exists in the hacks DataFrame, its value is used as a global upper limit for a constraint that limits the annual creation of the commodity “CO2”.

param model:urbs model object (not instance!)
param hacks:a DataFrame of hacks
return model:the modified urbs model object

Report & plotting

These two high-level functions cover the envisioned use of the unmodified urbs model and should cover most use cases.

urbs.plot(prob, com, sit[, timesteps=None])
Parameters:
  • prob – urbs model instance
  • com (str) – commodity name to plot
  • sit (str) – site name to plot
  • timesteps (list) – timesteps to plot, default: all
Return fig:

matplotlib figure handle

urbs.report(prob, filename, commodities, sites)

Write optimisation result summary to spreadsheet.

Parameters:
  • prob – urbs model instance
  • filename (str) – spreadsheet filename, will be overwritten if exists
  • commodities (list) – list of commodities for which to output timeseries
  • sites (list) – list sites for which to output timeseries

Retrieve results

While report() and plot() are quite flexible, custom result analysis scripts might be needed. These can be built on top of the following two medium-level functions. They retrieve all time-dependent and -independent quantities and return them as ready-to-use DataFrames.

urbs.get_constants(prob)

Return summary DataFrames for time-independent variables

Parameters:prob – urbs model instance
Returns:tuple of constants (costs, process, transmission, storage)
urbs.get_timeseries(prob, com, sit, timesteps=None)

Return DataFrames of all timeseries referring to a given commodity and site

Parameters:
  • prob – urbs model instance
  • com (str) – commodity name
  • sit (str) – site name
  • timesteps (list) – timesteps, default: all modelled timesteps
Returns:

tuple of timeseries (created, consumed, storage, imported, exported) tuple of DataFrames timeseries. These are:

  • created: timeseries of commodity creation, including stock source
  • consumed: timeseries of commodity consumption, including demand
  • storage: timeseries of commodity storage (level, stored, retrieved)
  • imported: timeseries of commodity import (by site)
  • exported: timeseries of commodity export (by site)

Persistence

To store valuable results for later analysis, or cross-scenario comparisons weeks after the original run, saving a problem instance with loaded results makes it possible to use one’s comparison scripts without having to solve the optimisation problem again. Simply load() the previously stored object using save():

urbs.save(prob, filename)

Save rivus model instance to a gzip’ed pickle file

Pickle is the standard Python way of serializing and de-serializing Python objects. By using it, saving any object, in case of this function a Pyomo ConcreteModel, becomes a twoliner.

GZip is a standard Python compression library that is used to transparently compress the pickle file further.

It is used over the possibly more compact bzip2 compression due to the lower runtime. Source: <http://stackoverflow.com/a/18475192/2375855>

Parameters:
  • prob – a rivus model instance
  • filename (str) – pickle file to be written
Returns:

nothing

urbs.load(filename)

Load a rivus model instance from a gzip’ed pickle file

Parameters:filename (str) – pickle file
Return prob:the unpickled rivus model instance

Low-level access

If the previous functions still don’t cut it, there are three low-level functions.

urbs.list_entities(prob, entity_type)
Parameters:
  • prob – urbs model instance
  • entity_type (str) – allowed values: set, par, var, con, obj
Returns:

a DataFrame with name, description and domain of entities

urbs.get_entity(prob, name)
Parameters:
  • prob – urbs model instance
  • name (str) – name of a model entity
Returns:

Series with values of model entity

urbs.get_entities(prob, names)
Parameters:
  • prob – urbs model instance
  • name (list) – list of model entity names
Returns:

DataFrame with values entities in columns

Only call get_entities for entities that share identical domains. This can be checked with list_entities(). For example, variable cap_pro naturally has the same domain as cap_pro_new.

Helper functions

urbs.annuity_factor(n, i)

Annuity factor formula.

Evaluates the annuity factor formula for depreciation duration and interest rate. Works also well for equally sized numpy arrays as input.

Parameters:
  • n (int) – number of depreciation periods (years)
  • i (float) – interest rate (e.g. 0.06 means 6 %)
Returns:

value of the expression \(\frac{(1+i)^n i}{(1+i)^n - 1}\)

urbs.commodity_balance(m, tm, sit, com)

Calculate commodity balance at given timestep.

For a given commodity, site and timestep, calculate the balance of consumed (to process/storage/transmission, counts positive) and provided (from process/storage/transmission, counts negative) energy. Used as helper function in create_model() for defining constraints on demand and stock commodities.

Parameters:
  • m – the ConcreteModel object
  • tm – the timestep number
  • sit – the site
  • co – the commodity
Returns:

amount of consumed (positive) or provided (negative) energy

urbs.split_columns(columns[, sep='.'])

Given a list of column labels containing a separator string (default: ‘.’), derive a MulitIndex that is split at the separator string.

Parameters:
  • columns (list) – column labels, each containing the separator string
  • sep (str) – the separator string (default: ‘.’)
Returns:

a MultiIndex corresponding to input, with levels split at separator

urbs.to_color(obj=None)

Assign a deterministic pseudo-random color to argument.

If COLORS[obj] is set, return that. Otherwise, create a deterministically random color from the hash() of that object. For strings, this value depends only on the string content, so that identical strings always yield the same color.

Parameters:obj – any hashable object
Returns:a (r,g,b) tuple if COLORS[obj] exists, otherwise a hexstring
urbs.COLORS

dict of process and site colors. Colors are stored as (r,g,b) tuples in range 0-255 each. To retrieve a color in a form usable with matplotlib, used the helper function to_color().

This snippet from the example script runme.py shows how to add custom colors:

# add or change plot colours
my_colors = {
    'South': (230, 200, 200),
    'Mid': (200, 230, 200),
    'North': (200, 200, 230)}
for country, color in my_colors.items():
    urbs.COLORS[country] = color