FZJ-IEK3-VSA / FINE

The FINE python package provides a framework for modeling, optimizing and assessing energy systems
https://vsa-fine.readthedocs.io
Other
69 stars 39 forks source link

Transmission with operationRateMax can not be initialized anymore #53

Closed maurerle closed 5 months ago

maurerle commented 6 months ago

The following small script worked with the old version but gives an error: ValueError: Can only compare identically-labeled Series objects:

import fine as fn
import pandas as pd
import numpy as np

esm = fn.EnergySystemModel(
    locations={"DE", "AT", "CH"},
    commodities={"energy"},
    commodityUnitsDict={"energy": "joule"})

operationRateMax = pd.DataFrame(index=range(8760))

operationRateMax["DE"] = 0.5
operationRateMax["DE_CH"] = 0.5
operationRateMax["AT_CH"] = 0.5
operationRateMax["AT_DE"] = 0.5
operationRateMax["CH_DE"] = 0.5
operationRateMax["CH_AT"] = 0.5

fn.Transmission(
    esM=esm,
    name="transmission",
    commodity="energy",
    operationRateMax=operationRateMax)

It raises:

Traceback (most recent call last):
  File "~/test.py", line 19, in <module>
    fn.Transmission(
  File "~/.conda/envs/py311/lib/python3.11/site-packages/fine/transmission.py", line 411, in __init__
    self.fullOperationRateMax = utils.checkAndSetInvestmentPeriodTimeSeries(
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/.conda/envs/py311/lib/python3.11/site-packages/fine/utils.py", line 1080, in checkAndSetInvestmentPeriodTimeSeries
    parameter[ip] = checkAndSetTimeSeries(
                    ^^^^^^^^^^^^^^^^^^^^^^
  File "~/.conda/envs/py311/lib/python3.11/site-packages/fine/utils.py", line 1134, in checkAndSetTimeSeries
    if (data > locationalEligibility).any().any():
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/.conda/envs/py311/lib/python3.11/site-packages/pandas/core/ops/common.py", line 76, in new_method
    return method(self, other)
           ^^^^^^^^^^^^^^^^^^^
  File "~/.conda/envs/py311/lib/python3.11/site-packages/pandas/core/arraylike.py", line 56, in __gt__
    return self._cmp_method(other, operator.gt)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "~/.conda/envs/py311/lib/python3.11/site-packages/pandas/core/series.py", line 6105, in _cmp_method
    raise ValueError("Can only compare identically-labeled Series objects")
ValueError: Can only compare identically-labeled Series objects

In the line if (data > locationalEligibility).any().any(): data is

AT       0.0
AT_CH    1.0
AT_DE    1.0
CH       0.0
CH_AT    1.0
CH_DE    1.0
DE       1.0
DE_CH    1.0
dtype: float64

while locationalEligibility is

AT_CH    1
AT_DE    1
CH_AT    1
CH_DE    1
DE_AT    1
DE_CH    1
dtype: int64

Could you help me resolve what is going on here? Looks like the countries themselves are missing in locationalEligibility?

Installation

I did the following:

conda create -n py311 python=3.11
pip install fine
pip install python-conv geopandas jupyter notebook libpysal pip descartes glpk openpyxl matplotlib xlrd pyomo numpy pandas networkx scipy scikit-learn>=1.2 xarray rasterio netcdf4 tsam pwlf psutil gurobi-logtools

python test.py
t-gross commented 6 months ago

Hey, the question for me is what you would like to express here with the maximum operation rate within a country. The transmission components are used to connect different modeled regions. Currently, you want to have a transmission within a region. That´s why you get this error message. What you can do: Only use:

operationRateMax["DE_CH"] = 0.5
operationRateMax["AT_CH"] = 0.5
operationRateMax["AT_DE"] = 0.5
operationRateMax["CH_DE"] = 0.5
operationRateMax["CH_AT"] = 0.5

and delete the line with "DE".

If you want to have a transmission within Germany, you would need to create two model regions.

maurerle commented 6 months ago

Thanks for taking a look at this. When removing the "DE" line, I still get the same error.

In the line if (data > locationalEligibility).any().any(): the data contains all single other countries too (see initial posting too).

This is taken from a code which worked before and breaks with the new version because of this

maurerle commented 6 months ago

When I add data = data[data > 0] after L1130 in utils.py it works, though I do not think that this is the right fix for this problem..?

t-gross commented 6 months ago

Thanks for reporting. Currently, the locational eligibility is set automatically if the parameter is not given. The code checks if capacities are given (capacityMax and capacityFix). If the component is not modelled with a capacity (hasCapacityVariable==False), the operation time series is used to fix the locational eligibility. In your case, the component is modelled with a capacity (hasCapacityVariable=True (default)). But you only give an operation rate. This case is currently not depicted in the code and need to be added.

k-knosala commented 5 months ago

@maurerle @t-gross The Transmission got the wrong dimensionality for creating missing values in operationRateMax. This should be fixed with 28fdc472e457401e68761cd217a989e3fac20ed9. Have a look at the develop branch to see the change. We will merge it into master in the next days.

Regarding your example: You are missing operationRateMax["DE_AT"] = 0.5 to define all possible connections. Also, operationRateMax["DE"] = 0.5 is not a valid index for the operation rate since the transmission components are only defined between regions.

Let me know if this solves your issue.

maurerle commented 5 months ago

Seems like my above snippet was part of investigating the differences between the prior FINE version. Below is the corrected snippet as you already mentioned, which works using the latest FINE version installed using:

pip install git+https://github.com/FZJ-IEK3-VSA/FINE@develop on a fresh conda create -n nice python=3.12

thanks @k-knosala !

import fine as fn
import pandas as pd

esm = fn.EnergySystemModel(
    locations={"DE", "AT", "CH"},
    commodities={"energy"},
    commodityUnitsDict={"energy": "joule"})

operationRateMax = pd.DataFrame(index=range(8760))

operationRateMax["DE_AT"] = 0.5
operationRateMax["DE_CH"] = 0.5
operationRateMax["AT_CH"] = 0.5
operationRateMax["AT_DE"] = 0.5
operationRateMax["CH_DE"] = 0.5
operationRateMax["CH_AT"] = 0.5

fn.Transmission(
    esM=esm,
    name="transmission",
    commodity="energy",
    operationRateMax=operationRateMax)