Structure

The purpose of the Structure class is primarily to specify the portfolios and timeseries we are interested in. This includes original Belvis portfolios, as well as synthetic ones that are the sum of several original porfolios. It also specifies where relevant prices can be found in Belvis.

It is used by the Tenant class, but can also be used stand-alone to load a structure file and investigate, which data is defined and how.

Initialisation

We can initialise a Structure instance by specifying the initialisation parameters. For example:

import belvys

structure = belvys.Structure(
   freq="D",
   tz="Europe/Berlin",
   pflines={
      "current_offtake": "Offtake volume in MW",
      "expected_offtake": ["Offtake volume in MW", "Expected churn in MW"],
      "forward_sourced": [
            "Procurement forward volume in MW",
            "Procurement forward cost in EUR",
      ],
   },
   portfolios={
      "original": ["B2C_household", "B2C_Spot", "B2B_backtoback", "B2B_Spot"]
   },
   prices={
      "fwc_monthly_DE": {"pfid": "Germany", "tsnames": "MPFC (THE)"},
      "fwc_daily_DE": {"pfid": "Germany", "tsnames": ["MPFC (THE)", "M2D profile"]},
   },
)

See the class documentation, below, for an explanation of the meaning of these parameters.

Alternatively, the specification can be stored in a yaml file, and used to initialise the class using the belvys.Structure.from_file() class method. Here is the file corresponding to the configuration above. It includes some comments for better understanding the format:

# Structure file to describe data in Belvis instance.
# Comments are used to indicate the expected specification format.
#
# This is a *basic* example, with only the most necessary data.

########
# Header
########

tz: Europe/Berlin 
freq: D                 # frequency to convert all data into before returning

#################
# Portfolio lines
#################

pflines:

# Here we define the portfolio lines we want to access for each portfolio. (We can make
# portfolio-specific corrections further below.) The keys ("pfline ids") in this section
# can be freely chosen; they point to timeseries names that exist in belvis.

  current_offtake: Offtake volume in MW
  # A pfline id can point to a single timeseries name. The unit of the timeseries is used 
  # to determine what information we have. (In this case, assuming the name is sensible, 
  # this is a volume timeseries, which is used to create a volume-only portfolio line).

  expected_offtake: 
  - Offtake volume in MW
  - Expected churn in MW
  # It can also point to a list of timeseries. In that case, timeseries with the same unit
  # unit are added. In this case, we again obtain a volume-only portfolio line...

  forward_sourced:
  - Procurement forward volume in MW
  - Procurement forward cost in EUR
  # ...and in this case, due to the distinct units, a price-and-volume portfolio line.

############
# Portfolios
############

portfolios:

# The portfolios we are interested in.
# This section has one part "original", and possibly also a part "sythetic".

  original: 
  - B2C_household
  - B2C_Spot
  - B2B_backtoback
  - B2B_Spot
  # This is a list of portfolio ids that are present in belvis. The list elements are the
  # portfolio ids (or "portfolio abbreviations", or "short names") as they are present in 
  # belvis. 

########
# Prices
########

prices:

# This section points to where market price timeseries are located in belvis.
# The keys ("price ids") in this section can be freely chosen; each is a dictionary 
# with keys 'pfid' and 'tsnames', indicating the belvis portfolio id and the timeseries 
# name of the price timeseries. Just as above; we can specify a single timeseries, an array
# of timeseries, or a nested structure.

  fwc_monthly_DE:
    pfid: Germany
    tsnames: MPFC (THE)
  # Just as above, we can specify a single timeseries...

  fwc_daily_DE:
    pfid: Germany
    tsnames: 
    - MPFC (THE)
    - M2D profile
  # ...or multiple ones, as long as they are in the same folder.

(download yaml 📄)

Usage

When the instance has been created, several methods tell us which data we expect to be available in Belvis:

  • .available_pfids() returns which portfolios are specified:

    structure.available_pfids()
    
    ['B2C_household', 'B2C_Spot', 'B2B_backtoback', 'B2B_Spot']
    
  • .available_pflineids() returns which portfolio lines are available for a given portfolio. In this case, for the first portfolio:

    structure.available_pflineids("B2C_household")
    
    {'expected_offtake', 'forward_sourced', 'current_offtake'}
    
  • .available_priceids() returns which prices are available. In this case:

    structure.available_priceids()
    
    dict_keys(['fwc_monthly_DE', 'fwc_daily_DE'])
    

Complex example

The example shown above is a basic one. Here is a more complex example file, which shows all possibilities to specify a Structure:

# Structure file to describe data in Belvis instance.
# Comments are used to indicate the expected specification format.
#
# This is a *complex* example, showcasing the full possibilities.

########
# Header
########

tz: Europe/Berlin 
freq: D                 # frequency to convert all data into before returning

#################
# Portfolio lines
#################

pflines:

# Here we define the portfolio lines we want to access for each portfolio. (We can make
# portfolio-specific corrections further below.) The keys ("pfline ids") in this section
# can be freely chosen; they point to timeseries names that exist in belvis.

  current_offtake: Offtake volume in MW
  # A pfline id can point to a single timeseries name. The unit of the timeseries is used 
  # to determine what information we have. (In this case, assuming the name is sensible, 
  # this is a volume timeseries, which is used to create a volume-only portfolio line).

  expected_offtake: 
  - Offtake volume in MW
  - Expected churn in MW
  # It can also point to a list of timeseries. In that case, timeseries with the same unit
  # unit are added. In this case, we again obtain a volume-only portfolio line...

  forward_sourced:
  - Procurement forward volume NCG in MW
  - Procurement forward volume Gaspool in MW
  - Procurement forward cost NCG in EUR
  - Procurement forward cost Gaspool in EUR
  # ...and in this case, due to the distinct units, a price-and-volume portfolio line.

  sourced_by_market:
    dayahead:
    - Procurement dayahead volume in MW
    - Procurement dayahead cost in EUR
    forward: forward_sourced # we can reuse definitions
  # Nesting is allowed. In this case, we obtain a nested portfolio line with children 
  # "forward" and "dayahead".

  sourced_by_market_and_product:
    dayahead:
    - Procurement dayahead volume in MW
    - Procurement dayahead cost in EUR
    forward:
      NCG:
      - Procurement forward volume NCG in MW
      - Procurement forward cost NCG in EUR
      Gaspool:
      - Procurement forward volume Gaspool in MW
      - Procurement forward cost Gaspool in EUR
  # Nesting is not limited to one level. Here, we have children "forward" and "dayahead",
  # with the "forward" child again having 2 children "NCG" and "Gaspool".

############
# Portfolios
############

portfolios:

# The portfolios we are interested in.
# This section has one part "original", and possibly also a part "sythetic".

  original: 
  - B2C_household
  - B2C_Spot
  - B2B_backtoback
  - B2B_Spot
  # This is a list of portfolio ids that are present in belvis. The list elements are the
  # portfolio ids (or "portfolio abbreviations", or "short names") as they are present in 
  # belvis. 

  synthetic:
  # In the sythetic part, we can create portfolios that do not exist in belvis but that we
  # are interested in nonetheless; they extend the portfolio ids that are available to the user.
  # The keys ("pfids") in this section can be freely chosen; they point to portfolio ids
  # that exist in belvis.

    B2B_BtB: B2B_backtoback  # Specifies an alias.
    # A pfid can point to a single existing portfolio id.

    B2B_all: [B2B_backtoback, B2B_Spot]
    B2C_all: [B2C_household, B2C_Spot]
    Spot_all: [B2C_Spot, B2B_Spot]
    all: [B2B_all, B2C_all] # We can reuse definitions.
    # It can also point to a several portfolio ids. These are added.

    # In order to avoid complexity, nesting is not allowed for portfolios.
    # This way, only the portfolio lines can cause nesting, and we don't have to think
    # about the nesting order.


##########################################
# Corrections: portfolio line vs portfolio 
##########################################

corrections: 

# This is a dictionary to make portfolio-specific corrections to the default portfolio 
# lines defined above. The keys are one or more of the pfids from the "original" list,
# above. If the default pfline definitions are correct for each of the original portfolios,
# no corrections are needed and this section can be removed.

  B2B_Spot: # pfid

    current_offtake: # existing pfline id
    - Initially contracted offtake volume in MW
    - Additional churn due to price increase
    # We can override the default definition by reusing the pfline id.

    expected_offtake: none
    # By setting it to none, we indicate it is not available for this portfolio.


  B2C_household:

    high_offtake_scenario: # new pfline id
    - expected_offtake
    - offtake growth bull market
    # We can also specify a new/additional pfline id that is only available in this portfolio.

########
# Prices
########

prices:

# This section points to where market price timeseries are located in belvis.
# The keys ("price ids") in this section can be freely chosen; each is a dictionary 
# with keys 'pfid' and 'tsnames', indicating the belvis portfolio id and the timeseries 
# name of the price timeseries. Just as above; we can specify a single timeseries, an array
# of timeseries, or a nested structure.

  fwc_monthly_DE:
    pfid: Germany
    tsnames: MPFC (THE)
  # Just as above, we can specify a single timeseries...

  fwc_daily_DE:
    pfid: Germany
    tsnames: 
    - MPFC (THE)
    - M2D profile
  # ...or multiple ones, as long as they are in the same folder...

  fwc_daily_DE_nested:
    pfid: Germany
    tsnames: 
      monthly: MPFC (THE)
      month_2_day: M2D profile
  # ...or multiple ones from the same folder, forming a nested structure.

(download yaml 📄)

Class Documentation

class belvys.Structure(freq: str, tz: str, pflines: ~typing.Dict[str, str | ~typing.Iterable[str] | ~typing.Dict[str, str | ~typing.Iterable[str] | ~typing.Dict[str, TsNameTree]]], portfolios: ~belvys.structure.Portfolios, prices: ~typing.Dict[str, ~typing.Dict[str, ~typing.Any]], corrections: ~typing.Dict[str, ~typing.Dict[str, str | ~typing.Iterable[str] | ~typing.Dict[str, str | ~typing.Iterable[str] | ~typing.Dict[str, TsNameTree]] | None]] = <factory>)

Structure of the belvis database; which portfolios and timeseries are of interest.

Parameters:
  • freq (str) – Frequency of the spot market, which is also the shortest frequency that is of interest, e.g. quarterhourly (‘15T’) for power and daily (‘D’) for gas. Ideally, all data in the Belvis database is available at this frequency.

  • tz (str) – The timezone of the spot market and the Belvis database. It is the timezone that the data is converted into.

  • pfline (Dict[str, TsNameTree]) –

    The portfolio lines that we are interested in. Dictionary with string keys (=pfline ids), which map onto the following possible values:

    • string value or list of string values (=timeseries name(s) as found in Belvis), which define a flat portfolio line (i.e., without children).

    • dictionary, which defines a mapping of child names onto timeseries name(s). May be nested.

  • portfolios (Portfolios) – The portfolios we are interested in. Dictionary with at least the key ‘original’ which maps onto a list of strings (= the ids (=short names) of portfolios as found in Belvis). May also have a key ‘synthetic’ which maps onto a dictionary, of which the keys are user-defined portfolio ids and the values are the original pfids that must be added.

  • prices (Dict[str, Dict[str, Any]]) – The prices we are interested in. Dictionary with string keys (=price ids), which map onto a dictionary that has the keys ‘pfid’ (which has the id of the portfolio as its value) and ‘tsnames’ (which has a (list of) timeseries names as its value).

  • corrections (Dict[str, Dict[str, TsNameTree | None]]) –

    If not all pflines can be found in all portfolios, we can specify this here.

    • If a portfolio has a pfline that is not found in the others (and therefore not specified in parameter pfline above), we can add a nested dictionary {pfid: {pflineid: tsnames}}.

    • If a porfolio does not have a pfline that is found in the others (and therefore specified in parameter pfline above), we can exclude it by adding the nested dictionary {pfid: {pflineid: None}}.

Notes

May be loaded from yaml file with the .from_file() class method.

available_pfids(original_only: bool = False) Iterable[str]

All available portfolio ids.

Parameters:

original_only (bool, optional (default: False)) – If True, only return the (“original”) portfolio ids that are present in belvis, and omit the (“synthetic”) ones that are created by summing.

Returns:

List of portfolio ids that exist in this tenant, according to the configuration.

Return type:

Iterable[str]

available_pflineids(pfid: str) Iterable[str]

All available portfolio line ids for a given portfolio.

Parameters:

pfid (str) – Id of portfolio. May be original or synthetic.

Returns:

Set of portfolio line ids that exist in this tenant and portfolio, according to the configuration.

Return type:

Iterable[str]

available_priceids() Iterable[str]

All available price ids for this tenant.

Parameters:

None

Returns:

List of price ids that exist in this tenant, according to the configuration.

Return type:

Iterable[str]

classmethod from_file(filepath: str | Path) Structure

Load structure from file.

Parameters:

filepath (str | pathlib.Path) – Path to load yaml structure file from.

to_original_pfids(pfid: str) Iterable[str]

The original pfids that need to be added to get values of wanted pfid.

Parameters:

pfid (str) – Id of portfolio. May be original or synthetic.

Returns:

List of original portfolio ids.

Return type:

Iterable[str]

tstree_pfline(pfid: str, pflineid: str) Ts | Iterable[Ts] | Dict[str, TsTree]

Timeseries that must be fetched to get the wanted pflineid for a given pfid.

Parameters:
  • pfid (str) – Id of portfolio. Must be original.

  • pflineid (str) – Id of portfolio line.

Returns:

Names of timeseries that must be fetched.

Return type:

TsTree

tstree_price(priceid: str) Ts | Iterable[Ts] | Dict[str, TsTree]

Timeseries that must be fetched to get the wanted price.

Parameters:

priceid (str) – Id of price.

Returns:

Timeseries that must be fetched.

Return type:

TsTree