From 134fff5bc87129ff3d936674f001313385b0c4d7 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 12:14:12 -0500 Subject: [PATCH 01/64] add back test-input --- tests/test-input.xml | 266 +++++++++++++++++++++++++++++++++++++++++++ tests/test_input.xml | 132 --------------------- 2 files changed, 266 insertions(+), 132 deletions(-) create mode 100644 tests/test-input.xml delete mode 100644 tests/test_input.xml diff --git a/tests/test-input.xml b/tests/test-input.xml new file mode 100644 index 00000000..dc8d1d6e --- /dev/null +++ b/tests/test-input.xml @@ -0,0 +1,266 @@ + + + + + 5 + 1 + 2000 + true + true + + + + + cycamore + Source + + + cycamore + Reactor + + + agents + NullRegion + + + cycamore + DeployInst + + + + + UOX_Source + + + uox + uox_fuel_recipe + 2.5 + + + + + + MOX_Source + + + mox + mox_fuel_recipe + 2.5 + + + + + + Reactor1 + + + + uox + mox + + + uox_fuel_recipe + mox_fuel_recipe + + + waste + waste + + + uox_used_fuel_recipe + mox_used_fuel_recipe + + + 0.1 + 1.0 + + 1 + 1 + 1 + 1 + 0 + 1 + mox + mox_fuel_recipe + mox_used_fuel_recipe + .928 + lwr_power + 4 + uox + 2.0 + + + + + + Reactor2 + + + + uox + mox + + + uox_fuel_recipe + mox_fuel_recipe + + + waste + waste + + + uox_used_fuel_recipe + mox_used_fuel_recipe + + + 0.1 + 1.0 + + 1 + 1 + 1 + 1 + 0 + 1 + mox + mox_fuel_recipe + mox_used_fuel_recipe + .928 + lwr_power + + + + + + Reactor3 + + + + uox + mox + + + uox_fuel_recipe + mox_fuel_recipe + + + waste + waste + + + uox_used_fuel_recipe + mox_used_fuel_recipe + + + 0.1 + 0.5 + + 1 + 1 + 1 + 1 + 0 + 1 + mox + mox_fuel_recipe + mox_used_fuel_recipe + .928 + lwr_power + + + + + + SingleRegion + + + + + SingleInstitution + + + + UOX_Source + MOX_Source + Reactor1 + Reactor2 + Reactor3 + + + 1 + 1 + 1 + 2 + 3 + + + 1 + 1 + 1 + 1 + 1 + + + + + + + + natl_u + mass + 922350000 0.711 + 922380000 99.289 + + + + uox_fuel_recipe + mass + 922350000 4.0 + 922380000 96.0 + + + + uox_used_fuel_recipe + mass + 922350000 156.729 + 922360000 102.103 + 922380000 18280.324 + 932370000 13.656 + 942380000 5.043 + 942390000 106.343 + 942400000 41.357 + 942410000 36.477 + 942420000 15.387 + 952410000 1.234 + + 952430000 3.607 + 962440000 0.431 + 962450000 1.263 + + + + mox_fuel_recipe + mass + 922340000 0.0002 + 922350000 0.0018 + 922360000 0.01 + 9223800000.8973 + 942380000 0.0032 + 942390000 0.0507 + 942400000 0.0247 + 942410000 0.0134 + 942420000 0.0085 + 080160000 0.13 + + + + mox_used_fuel_recipe + mass + 922350000 0.01 + 922380000 0.94 + 922360000 0.03 + 080160000 0.13 + 942390000 0.02 + + + diff --git a/tests/test_input.xml b/tests/test_input.xml deleted file mode 100644 index 59a2aa1d..00000000 --- a/tests/test_input.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - - - 20 - 1 - 2000 - - - - - cycamore - Source - - - cycamore - Reactor - - - agents - NullRegion - - - cycamore - DeployInst - - - - - Source - - - uox - uox_fuel_recipe - 10000 - - - - - - Reactor1 - - - - uox - - - uox_fuel_recipe - - - waste - - - uox_used_fuel_recipe - - 1 - 1 - 1 - 1 - 0 - 1 - lwr_power - - - - - - - Region1 - - - - - Institution1 - - - - Source - Reactor1 - - - 1 - 1 - - - 1 - 1 - - - -1 - 10 - - - - - - - - - natl_u - mass - 922350000 0.711 - 922380000 99.289 - - - - uox_fuel_recipe - mass - 922350000 4.0 - 922380000 96.0 - - - - uox_used_fuel_recipe - mass - 922350000 156.729 - 922360000 102.103 - 922380000 18280.324 - 932370000 13.656 - 942380000 5.043 - 942390000 106.343 - 942400000 41.357 - 942410000 36.477 - 942420000 15.387 - 952410000 1.234 - - 952430000 3.607 - 962440000 0.431 - 962450000 1.263 - - - From a26aa5d5ebce3e5b44c7aec6bc3e17882c007455 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 14:03:05 -0500 Subject: [PATCH 02/64] adding matplotlib in CI --- circle.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/circle.yml b/circle.yml index 1a7f7147..6e435b76 100644 --- a/circle.yml +++ b/circle.yml @@ -9,6 +9,7 @@ jobs: steps: # Ensure your image has git (required by git to clone via SSH) so that CircleCI can clone your repo - run: apt-get -qq update; apt-get -y install git openssh-client + - run: pip install matplotlib - checkout - run: name: Build Cymetric From 4b2062840482f7243c0a5a4a4eab5a4b314e4ad7 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 14:11:04 -0500 Subject: [PATCH 03/64] adding matplotlib in CI --- circle.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/circle.yml b/circle.yml index 6e435b76..84ef5113 100644 --- a/circle.yml +++ b/circle.yml @@ -38,6 +38,7 @@ jobs: - run: name: Install nosetest command: pip install nose + - run: pip install matplotlib - run: name: Nosetests command: nosetests -w ~/cymetric/tests; exit $? From 470171eb7c50717f79c426c2373f002a38bfb800 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 14:28:49 -0500 Subject: [PATCH 04/64] change eco_inputs for eco_tools --- cymetric/eco_metrics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index d48c3a8d..8795dd0f 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -14,7 +14,7 @@ from cymetric.tools import dbopen from cymetric.evaluator import Evaluator -from cymetric.eco_inputs import actualization_vector, isreactor +from cymetric.eco_tools import actualization_vector, isreactor try: from cymetric.metrics import metric @@ -1441,4 +1441,4 @@ def simulation_average_lcoe(outputDb): rtn['Power'] += rtn['Temp2'].fillna(0) print(id) # test rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] - return rtn.fillna(0) \ No newline at end of file + return rtn.fillna(0) From dea0aba4cfc77ba7472c21d5a676fa8933b635fc Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 14:36:59 -0500 Subject: [PATCH 05/64] cleaning --- cymetric/eco_metrics.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 8795dd0f..a1a3e37e 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -12,27 +12,22 @@ import matplotlib.pyplot as plt import warnings -from cymetric.tools import dbopen -from cymetric.evaluator import Evaluator -from cymetric.eco_tools import actualization_vector, isreactor +from cyclus import typesystem as ts + try: from cymetric.metrics import metric - from cymetric import cyclus - from cymetric import schemas - from cymetric import typesystem as ts - from cymetric import tools + from cymetric.tools import dbopen + from cymetric.evaluator import Evaluator + from cymetric.eco_tools import actualization_vector, isreactor, capital_shape from cymetric.evaluator import register_metric - from cymetric.eco_tools import capital_shape, isreactor except ImportError: # some wacky CI paths prevent absolute importing, try relative from .metrics import metric - from . import cyclus - from . import schemas - from . import typesystem as ts - from . import tools from .evaluator import register_metric - from .eco_tools import capital_shape, isreactor + from .eco_tools import capital_shape, isreactor, actualization_vector, isreactor + from .tools import dbopen + from .evaluator import Evaluator xml_inputs = 'parameters.xml' # This xml file has to be built in the same direction as the sqlite output database. It contains the economic data needed to calculate the EconomicInfo metric From 574d133daa909c7256d62d545076f983ab49bd7a Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 14:38:02 -0500 Subject: [PATCH 06/64] not need of matplotlib --- circle.yml | 2 -- cymetric/eco_metrics.py | 1 - 2 files changed, 3 deletions(-) diff --git a/circle.yml b/circle.yml index 84ef5113..1a7f7147 100644 --- a/circle.yml +++ b/circle.yml @@ -9,7 +9,6 @@ jobs: steps: # Ensure your image has git (required by git to clone via SSH) so that CircleCI can clone your repo - run: apt-get -qq update; apt-get -y install git openssh-client - - run: pip install matplotlib - checkout - run: name: Build Cymetric @@ -38,7 +37,6 @@ jobs: - run: name: Install nosetest command: pip install nose - - run: pip install matplotlib - run: name: Nosetests command: nosetests -w ~/cymetric/tests; exit $? diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index a1a3e37e..70eeaf11 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -9,7 +9,6 @@ import xml.etree.ElementTree as ET import math import os -import matplotlib.pyplot as plt import warnings from cyclus import typesystem as ts From 25a65fbaa5807c5a2b8eee7ca17cb2db9ee3714a Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 14:55:14 -0500 Subject: [PATCH 07/64] any better? --- cymetric/eco_metrics.py | 2 +- tests/test_eco_metrics.py | 202 +++++++++++++++++++------------------- 2 files changed, 102 insertions(+), 102 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 70eeaf11..f644ae88 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -226,7 +226,7 @@ def operation_maintenance(series): _eideps = [('AgentEntry', ('AgentId', 'Prototype'), 'ParentId')] -_eischema = [(('Agent', 'Prototype'), ts.STRING), (('Agent', 'AgentId'), ts.INT), (('Agent', 'ParentId'), ts.INT), (('Finance','ReturnOnDebt'), ts.DOUBLE), (('Finance','ReturnOnEquity'), ts.DOUBLE), (('Finance','TaxRate'), ts.DOUBLE), (('Finance','DiscountRate'), ts.DOUBLE), (('Capital', 'beforePeak'), ts.INT), (('Capital', 'afterPeak'), ts.INT), (('Capital', 'constructionDuration'), ts.INT), (('Capital', 'Deviation'), ts.DOUBLE), (('Capital', 'OvernightCost'), ts.DOUBLE), (('Decommissioning', 'Duration'), ts.INT), (('Decommissioning', 'OvernightCost'), ts.DOUBLE), (('OperationMaintenance', 'FixedCost'), ts.DOUBLE), (('OperationMaintenance', 'VariableCost'), ts.DOUBLE), (('OperationMaintenance', 'Deviation'), ts.DOUBLE), (('Fuel', 'Commodity'), ts.STRING), (('Fuel', 'SupplyCost'), ts.DOUBLE), (('Fuel', 'WasteFee'), ts.DOUBLE), (('Fuel', 'Deviation'), ts.DOUBLE), (('Truncation', 'Begin'), ts.INT), (('Truncation', 'End'), ts.INT)] +_eischema = [('Agent_Prototype', ts.STRING), (('Agent', 'AgentId'), ts.INT), (('Agent', 'ParentId'), ts.INT), (('Finance','ReturnOnDebt'), ts.DOUBLE), (('Finance','ReturnOnEquity'), ts.DOUBLE), (('Finance','TaxRate'), ts.DOUBLE), (('Finance','DiscountRate'), ts.DOUBLE), (('Capital', 'beforePeak'), ts.INT), (('Capital', 'afterPeak'), ts.INT), (('Capital', 'constructionDuration'), ts.INT), (('Capital', 'Deviation'), ts.DOUBLE), (('Capital', 'OvernightCost'), ts.DOUBLE), (('Decommissioning', 'Duration'), ts.INT), (('Decommissioning', 'OvernightCost'), ts.DOUBLE), (('OperationMaintenance', 'FixedCost'), ts.DOUBLE), (('OperationMaintenance', 'VariableCost'), ts.DOUBLE), (('OperationMaintenance', 'Deviation'), ts.DOUBLE), (('Fuel', 'Commodity'), ts.STRING), (('Fuel', 'SupplyCost'), ts.DOUBLE), (('Fuel', 'WasteFee'), ts.DOUBLE), (('Fuel', 'Deviation'), ts.DOUBLE), (('Truncation', 'Begin'), ts.INT), (('Truncation', 'End'), ts.INT)] @metric(name='EconomicInfo', depends=_eideps, schema=_eischema) def economic_info(series): diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index aab1e95c..df894400 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -28,8 +28,8 @@ def test_capital_cost(): (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 5, 0.028035), (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 6, 0.0) ], dtype=ensure_dt_bytes([ - ('SimId','O'), ('AgentId', ' Date: Thu, 23 Apr 2020 15:15:09 -0500 Subject: [PATCH 08/64] fix schema --- cymetric/eco_metrics.py | 375 +++++++++++++++++++++------------------- 1 file changed, 194 insertions(+), 181 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index f644ae88..4fc2ca37 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -226,7 +226,20 @@ def operation_maintenance(series): _eideps = [('AgentEntry', ('AgentId', 'Prototype'), 'ParentId')] -_eischema = [('Agent_Prototype', ts.STRING), (('Agent', 'AgentId'), ts.INT), (('Agent', 'ParentId'), ts.INT), (('Finance','ReturnOnDebt'), ts.DOUBLE), (('Finance','ReturnOnEquity'), ts.DOUBLE), (('Finance','TaxRate'), ts.DOUBLE), (('Finance','DiscountRate'), ts.DOUBLE), (('Capital', 'beforePeak'), ts.INT), (('Capital', 'afterPeak'), ts.INT), (('Capital', 'constructionDuration'), ts.INT), (('Capital', 'Deviation'), ts.DOUBLE), (('Capital', 'OvernightCost'), ts.DOUBLE), (('Decommissioning', 'Duration'), ts.INT), (('Decommissioning', 'OvernightCost'), ts.DOUBLE), (('OperationMaintenance', 'FixedCost'), ts.DOUBLE), (('OperationMaintenance', 'VariableCost'), ts.DOUBLE), (('OperationMaintenance', 'Deviation'), ts.DOUBLE), (('Fuel', 'Commodity'), ts.STRING), (('Fuel', 'SupplyCost'), ts.DOUBLE), (('Fuel', 'WasteFee'), ts.DOUBLE), (('Fuel', 'Deviation'), ts.DOUBLE), (('Truncation', 'Begin'), ts.INT), (('Truncation', 'End'), ts.INT)] +_eischema = [('Agent_Prototype', ts.STRING), ('Agent_AgentId', ts.INT), + ('Agent_ParentId', ts.INT), ('Finance_ReturnOnDebt', ts.DOUBLE), + ('Finance_ReturnOnEquity', ts.DOUBLE), ('Finance_TaxRate', ts.DOUBLE), + ('Finance_DiscountRate', ts.DOUBLE), ('Capital_beforePeak', ts.INT), + ('Capital_afterPeak', ts.INT), ('Capital_constructionDuration', ts.INT), + ('Capital_Deviation', ts.DOUBLE), ('Capital_OvernightCost', ts.DOUBLE), + ('Decommissioning_Duration', ts.INT), + ('Decommissioning_OvernightCost', ts.DOUBLE), + ('OperationMaintenance_FixedCost', ts.DOUBLE), + ('OperationMaintenance_VariableCost', ts.DOUBLE), + ('OperationMaintenance_Deviation', ts.DOUBLE), + ('FuelCommodity', ts.STRING), ('Fuel_SupplyCost', ts.DOUBLE), + ('Fuel_WasteFee', ts.DOUBLE), ('Fuel_Deviation', ts.DOUBLE), + ('Truncation_Begin', ts.INT), ('Truncation_End', ts.INT)] @metric(name='EconomicInfo', depends=_eideps, schema=_eischema) def economic_info(series): @@ -238,37 +251,37 @@ def economic_info(series): dfEntry = series[0].reset_index() agentIndex = dfEntry.reset_index().set_index('AgentId')['index'] rtn = rtn.T - rtn[('Agent', 'Prototype')] = dfEntry['Prototype'] - rtn[('Agent', 'AgentId')] = dfEntry['AgentId'] - rtn[('Agent', 'ParentId')] = dfEntry['ParentId'] + rtn['Agent_Prototype')] = dfEntry['Prototype'] + rtn['Agent_AgentId'] = dfEntry['AgentId'] + rtn['Agent_ParentId'] = dfEntry['ParentId'] parametersInput = 'parameters.xml' tree = ET.parse(parametersInput) root = tree.getroot() truncation = root.find('truncation') - rtn[('Truncation', 'Begin')] = int(truncation.find('simulation_begin').text) - rtn[('Truncation', 'End')] = int(truncation.find('simulation_end').text) + rtn['Truncation_Begin'] = int(truncation.find('simulation_begin').text) + rtn['Truncation_End'] = int(truncation.find('simulation_end').text) finance = root.find('finance') if not finance == None: - rtn.loc[:, ('Finance', 'TaxRate')] = float(finance.find('tax_rate').text) - rtn.loc[:, ('Finance', 'ReturnOnDebt')] = float(finance.find('return_on_debt').text) - rtn.loc[:, ('Finance', 'ReturnOnEquity')] = float(finance.find('return_on_equity').text) - rtn.loc[:, ('Finance', 'DiscountRate')] = float(finance.find('discount_rate').text) + rtn.loc[:, 'Finance_TaxRate'] = float(finance.find('tax_rate').text) + rtn.loc[:, 'Finance_ReturnOnDebt'] = float(finance.find('return_on_debt').text) + rtn.loc[:, 'Finance_ReturnOnEquity'] = float(finance.find('return_on_equity').text) + rtn.loc[:, 'Finance_DiscountRate'] = float(finance.find('discount_rate').text) capital = root.find('capital') if not capital == None: - rtn.loc[:, ('Capital', 'beforePeak')] = int(capital.find('beforePeak').text) - rtn.loc[:, ('Capital', 'afterPeak')] = int(capital.find('afterPeak').text) - rtn.loc[:, ('Capital', 'constructionDuration')] = int(capital.find('constructionDuration').text) - rtn.loc[:, ('Capital', 'Deviation')] = float(capital.find('deviation').text) - rtn.loc[:, ('Capital', 'OvernightCost')] = float(capital.find('overnight_cost').text) + rtn.loc[:, 'Capital_beforePeak'] = int(capital.find('beforePeak').text) + rtn.loc[:, 'Capital_afterPeak'] = int(capital.find('afterPeak').text) + rtn.loc[:, 'Capital_constructionDuration'] = int(capital.find('constructionDuration').text) + rtn.loc[:, 'Capital_Deviation'] = float(capital.find('deviation').text) + rtn.loc[:, 'Capital_OvernightCost'] = float(capital.find('overnight_cost').text) decommissioning = root.find('decommissioning') if not decommissioning == None: - rtn.loc[:, ('Decommissioning', 'Duration')] = int(decommissioning.find('duration').text) - rtn.loc[:, ('Decommissioning', 'OvernightCost')] = float(decommissioning.find('overnight_cost').text) + rtn.loc[:, 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) + rtn.loc[:, 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) operation_maintenance = root.find('operation_maintenance') if not operation_maintenance == None: - rtn.loc[:, ('OperationMaintenance', 'FixedCost')] = float(operation_maintenance.find('fixed').text) - rtn.loc[:, ('OperationMaintenance', 'VariableCost')] = float(operation_maintenance.find('variable').text) - rtn.loc[:, ('OperationMaintenance', 'Deviation')] = float(operation_maintenance.find('deviation').text) + rtn.loc[:, 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) + rtn.loc[:, 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) + rtn.loc[:, 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) fuel = root.find('fuel') indexCopy = rtn.index.copy() if not fuel == None: @@ -278,18 +291,18 @@ def economic_info(series): name = type.find('name').text deviation = float(type.find('deviation').text) for j in indexCopy: - if np.isnan(rtn.loc[j, ('Fuel', 'SupplyCost')]): - rtn.loc[j, ('Fuel', 'Commodity')] = name - rtn.loc[j, ('Fuel', 'SupplyCost')] = supply - rtn.loc[j, ('Fuel', 'WasteFee')] = waste - rtn.loc[j, ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[j, 'Fuel_SupplyCost']): + rtn.loc[j, 'Fuel_Commodity'] = name + rtn.loc[j, 'Fuel_SupplyCost'] = supply + rtn.loc[j, 'Fuel_WasteFee'] = waste + rtn.loc[j, 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[j] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for region in root.findall('region'): idRegion = int(region.find('id').text) finance = region.find('finance') @@ -298,20 +311,20 @@ def economic_info(series): returnOnEquity = float(finance.find('return_on_equity').text) taxRate = float(finance.find('tax_rate').text) discountRate = float(finance.find('discount_rate').text) - rtn.loc[agentIndex[idRegion], ('Finance', 'TaxRate')] = taxRate - rtn.loc[agentIndex[idRegion], ('Finance','ReturnOnDebt')] = returnOnDebt - rtn.loc[agentIndex[idRegion],('Finance','ReturnOnEquity')] = returnOnEquity - rtn.loc[gent_index[idRegion], ('Finance','DiscountRate')] = discountRate + rtn.loc[agentIndex[idRegion], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idRegion], 'Finance_DiscountRate'] = discountRate for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], ('Finance', 'TaxRate')] = taxRate - rtn.loc[agentIndex[idInstitution], ('Finance','ReturnOnDebt')] = returnOnDebt - rtn.loc[agentIndex[idInstitution], ('Finance','ReturnOnEquity')] = returnOnEquity - rtn.loc[gent_index[idInstitution], ('Finance','DiscountRate')] = discountRate + rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('Finance', 'TaxRate')] = taxRate - rtn.loc[agentIndex[idFacility], ('Finance','ReturnOnDebt')] = returnOnDebt - rtn.loc[agentIndex[idFacility], ('Finance','ReturnOnEquity')] = returnOnEquity - rtn.loc[gent_index[idFacility], ('Finance','DiscountRate')] = discountRate + rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate capital = region.find('capital') if capital is not None: beforePeak = int(capital.find('beforePeak').text) @@ -319,51 +332,51 @@ def economic_info(series): constructionDuration = int(capital.find('constructionDuration').text) deviation = float(capital.find('deviation').text) overnightCost = float(capital.find('overnight_cost').text) - rtn.loc[agentIndex[idRegion], ('Capital', 'beforePeak')] = beforePeak - rtn.loc[agentIndex[idRegion], ('Capital', 'afterPeak')] = afterPeak - rtn.loc[agentIndex[idRegion], ('Capital', 'constructionDuration')] = constructionDuration - rtn.loc[agentIndex[idRegion], ('Capital', 'Deviation')] = deviation - rtn.loc[agentIndex[idRegion], ('Capital', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idRegion], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idRegion], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idRegion], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idRegion], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idRegion], 'Captial_OvernightCost'] = overnightCost for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], ('Capital', 'beforePeak')] = beforePeak - rtn.loc[agentIndex[idInstitution], ('Capital', 'afterPeak')] = afterPeak - rtn.loc[agentIndex[idInstitution], ('Capital', 'constructionDuration')] = constructionDuration - rtn.loc[agentIndex[idInstitution], ('Capital', 'Deviation')] = deviation - rtn.loc[agentIndex[idInstitution], ('Capital', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('Capital', 'beforePeak')] = beforePeak - rtn.loc[agentIndex[idFacility], ('Capital', 'afterPeak')] = afterPeak - rtn.loc[agentIndex[idFacility], ('Capital', 'constructionDuration')] = constructionDuration - rtn.loc[agentIndex[idFacility], ('Capital', 'Deviation')] = deviation - rtn.loc[agentIndex[idFacility], ('Capital', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost decommissioning = region.find('decommissioning') if decommissioning is not None: duration = int(decommissioning.find('duration').text) overnightCost = float(decommissioning.find('overnight_cost').text) - rtn.loc[agentIndex[idRegion], ('Decommissioning', 'Duration')] = duration - rtn.loc[agentIndex[idRegion], ('Decommissioning', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idRegion], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idRegion], 'Decommissioning_OvernightCost'] = overnightCost for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], ('Decommissioning', 'Duration')] = duration - rtn.loc[agentIndex[idInstitution], ('Decommissioning', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'Duration')] = duration - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost operation_maintenance = region.find('operation_maintenance') if operation_maintenance is not None: fixed = float(operation_maintenance.find('fixed').text) variable = float(operation_maintenance.find('variable').text) deviation = float(operation_maintenance.find('deviation').text) - rtn.loc[agentIndex[idRegion], ('OperationMaintenance', 'FixedCost')] = fixed - rtn.loc[agentIndex[idRegion], ('OperationMaintenance', 'VariableCost')] = variable - rtn.loc[agentIndex[idRegion], ('OperationMaintenance', 'Deviation')] = deviation + rtn.loc[agentIndex[idRegion], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idRegion], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idRegion], 'OperationMaintenance_Deviation'] = deviation for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], ('OperationMaintenance', 'FixedCost')] = fixed - rtn.loc[agentIndex[idInstitution], ('OperationMaintenance', 'VariableCost')] = variable - rtn.loc[agentIndex[idInstitution], ('OperationMaintenance', 'Deviation')] = deviation + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'FixedCost')] = fixed - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'VariableCost')] = variable - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'Deviation')] = deviation + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation fuel = region.find('fuel') if fuel is not None: for type in fuel.findall('type'): @@ -371,44 +384,44 @@ def economic_info(series): waste = float(type.find('waste_fee').text) name = type.find('name').text deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idRegion], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idRegion], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idRegion], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idRegion], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idRegion], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idRegion], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idRegion], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idRegion], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idRegion]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idInstitution], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idInstitution], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idInstitution], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idInstitution], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idInstitution], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idFacility], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idFacility], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idFacility], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for institution in region.findall('institution'): idInstitution = int(institution.find('id').text) finance = institution.find('finance') @@ -417,15 +430,15 @@ def economic_info(series): returnOnEquity = float(finance.find('return_on_equity').text) taxRate = float(finance.find('tax_rate').text) discountRate = float(finance.find('discount_rate').text) - rtn.loc[agentIndex[idInstitution], ('Finance', 'TaxRate')] = taxRate - rtn.loc[agentIndex[idInstitution], ('Finance','ReturnOnDebt')] = returnOnDebt - rtn.loc[agentIndex[idInstitution],('Finance','ReturnOnEquity')] = returnOnEquity - rtn.loc[gent_index[idInstitution], ('Finance','DiscountRate')] = discountRate + rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idInstitution],'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('Finance', 'TaxRate')] = taxRate - rtn.loc[agentIndex[idFacility], ('Finance','ReturnOnDebt')] = returnOnDebt - rtn.loc[agentIndex[idFacility], ('Finance','ReturnOnEquity')] = returnOnEquity - rtn.loc[gent_index[idFacility], ('Finance','DiscountRate')] = discountRate + rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate capital = institution.find('capital') if capital is not None: beforePeak = int(capital.find('beforePeak').text) @@ -433,37 +446,37 @@ def economic_info(series): constructionDuration = int(capital.find('constructionDuration').text) deviation = float(capital.find('deviation').text) overnightCost = float(capital.find('overnight_cost').text) - rtn.loc[agentIndex[idInstitution], ('Capital', 'beforePeak')] = beforePeak - rtn.loc[agentIndex[idInstitution], ('Capital', 'afterPeak')] = afterPeak - rtn.loc[agentIndex[idInstitution], ('Capital', 'constructionDuration')] = constructionDuration - rtn.loc[agentIndex[idInstitution], ('Capital', 'Deviation')] = deviation - rtn.loc[agentIndex[idInstitution], ('Capital', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('Capital', 'beforePeak')] = beforePeak - rtn.loc[agentIndex[idFacility], ('Capital', 'constructionDuration')] = constructionDuration - rtn.loc[agentIndex[idFacility], ('Capital', 'Deviation')] = deviation - rtn.loc[agentIndex[idFacility], ('Capital', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost decommissioning = institution.find('decommissioning') if decommissioning is not None: duration = int(decommissioning.find('duration').text) overnightCost = float(decommissioning.find('overnight_cost').text) - rtn.loc[agentIndex[idInstitution], ('Decommissioning', 'Duration')] = duration - rtn.loc[agentIndex[idInstitution], ('Decommissioning', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'Duration')] = duration - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'OvernightCost')] = overnightCost + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost operation_maintenance = institution.find('operation_maintenance') if operation_maintenance is not None: fixed = float(operation_maintenance.find('fixed').text) variable = float(operation_maintenance.find('variable').text) deviation = float(operation_maintenance.find('deviation').text) - rtn.loc[agentIndex[idInstitution], ('OperationMaintenance', 'FixedCost')] = fixed - rtn.loc[agentIndex[idInstitution], ('OperationMaintenance', 'VariableCost')] = variable - rtn.loc[agentIndex[idInstitution], ('OperationMaintenance', 'Deviation')] = deviation + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'FixedCost')] = fixed - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'VariableCost')] = variable - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'Deviation')] = deviation + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation fuel = institution.find('fuel') if fuel is not None: for type in fuel.findall('type'): @@ -471,31 +484,31 @@ def economic_info(series): waste = float(type.find('waste_fee').text) name = type.find('name').text deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idInstitution], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idInstitution], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idInstitution], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idInstitution], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idInstitution], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idFacility], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idFacility], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idFacility], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for prototype in institution.findall('prototype'): name = prototype.find('name').text tmp = dfEntry[dfEntry.ParentId==idInstitution] @@ -508,20 +521,20 @@ def economic_info(series): deviation = float(capital.find('deviation').text) overnight = float(capital.find('overnight_cost').text) for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], ('Capital', 'beforePeak')] = beforePeak - rtn.loc[agentIndex[idFacility], ('Capital', 'afterPeak')] = afterPeak - rtn.loc[agentIndex[idFacility], ('Capital', 'constructionDuration')] = constructionDuration - rtn.loc[agentIndex[idFacility], ('Capital', 'Deviation')] = deviation - rtn.loc[agentIndex[idFacility], ('Capital', 'OvernightCost')] = overnight + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnight operation_maintenance = prototype.find('operation_maintenance') if operation_maintenance is not None: fixed = float(operation_maintenance.find('fixed').text) variable = float(operation_maintenance.find('variable').text) deviation = float(operation_maintenance.find('deviation').text) for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'FixedCost')] = fixed - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'VariableCost')] = variable - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'Deviation')] = deviation + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation fuel = prototype.find('fuel') if fuel is not None: for type in fuel.findall('type'): @@ -530,39 +543,39 @@ def economic_info(series): name = type.find('name').text deviation = float(type.find('deviation').text) for idFacility in facilityIdList: - if np.isnan(rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idFacility], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idFacility], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idFacility], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation decommissioning = prototype.find('decommissioning') if decommissioning is not None: duration = int(decommissioning.find('duration').text) overnight = float(decommissioning.find('overnight_cost').text) for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'Duration')] = duration - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'OvernightCost')] = overnight + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnight for facility in prototype.findall('facility'): idFacility = int(facility.find('id').text) capital = facility.find('capital') if capital is not None: - rtn.loc[agentIndex[idFacility], ('Capital', 'beforePeak')] = int(capital.find('beforePeak').text) - rtn.loc[agentIndex[idFacility], ('Capital', 'afterPeak')] = int(capital.find('afterPeak').text) - rtn.loc[agentIndex[idFacility], ('Capital', 'constructionDuration')] = int(capital.find('constructionDuration').text) - rtn.loc[agentIndex[idFacility], ('Capital', 'Deviation')] = float(capital.find('deviation').text) - rtn.loc[agentIndex[idFacility], ('Capital', 'OvernightCost')] = float(capital.find('overnight_cost').text) + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = int(capital.find('beforePeak').text) + rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = int(capital.find('afterPeak').text) + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = int(capital.find('constructionDuration').text) + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = float(capital.find('deviation').text) + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = float(capital.find('overnight_cost').text) operation_maintenance = facility.find('operation_maintenance') if operation_maintenance is not None: - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'FixedCost')] = float(operation_maintenance.find('fixed').text) - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'VariableCost')] = float(operation_maintenance.find('variable').text) - rtn.loc[agentIndex[idFacility], ('OperationMaintenance', 'Deviation')] = float(operation_maintenance.find('deviation').text) + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) fuel = facility.find('fuel') if fuel is not None: for type in fuel.findall('type'): @@ -570,22 +583,22 @@ def economic_info(series): waste = float(type.find('waste_fee').text) name = type.find('name').text deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')]): - rtn.loc[agentIndex[idFacility], ('Fuel', 'Commodity')] = name - rtn.loc[agentIndex[idFacility], ('Fuel', 'SupplyCost')] = supply - rtn.loc[agentIndex[idFacility], ('Fuel', 'WasteFee')] = waste - rtn.loc[agentIndex[idFacility], ('Fuel', 'Deviation')] = deviation + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation else: indice = rtn.index.size rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, ('Fuel', 'Commodity')] = name - rtn.loc[indice, ('Fuel', 'SupplyCost')] = supply - rtn.loc[indice, ('Fuel', 'WasteFee')] = waste - rtn.loc[indice, ('Fuel', 'Deviation')] = deviation + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation decommissioning = facility.find('decommissioning') if decommissioning is not None: - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'Duration')] = int(decommissioning.find('duration').text) - rtn.loc[agentIndex[idFacility], ('Decommissioning', 'OvernightCost')] = float(decommissioning.find('overnight_cost').text) + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) return rtn del _eideps, _eischema From 9f818d90bc2fe5f1b4b2a46388a08e0470e90f4e Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 15:28:16 -0500 Subject: [PATCH 09/64] fix schema (bis) --- cymetric/eco_metrics.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 4fc2ca37..666d1ac8 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -245,13 +245,22 @@ def operation_maintenance(series): def economic_info(series): """The EconomicInfo metric stores all economic data needed to calculate the economic metrics. These economic parameters are originally written in 'parameters.xml'. """ - tuples = [('Agent', 'Prototype'), ('Agent', 'AgentId'), ('Agent', 'ParentId'), ('Finance','ReturnOnDebt'), ('Finance','ReturnOnEquity'), ('Finance','TaxRate'), ('Finance','DiscountRate'), ('Capital', 'beforePeak'), ('Capital', 'afterPeak'), ('Capital', 'constructionDuration'), ('Capital', 'Deviation'), ('Capital', 'OvernightCost'), ('Decommissioning', 'Duration'), ('Decommissioning', 'OvernightCost'), ('OperationMaintenance', 'FixedCost'), ('OperationMaintenance', 'VariableCost'), ('OperationMaintenance', 'Deviation'), ('Fuel', 'Commodity'), ('Fuel', 'SupplyCost'), ('Fuel', 'WasteFee'), ('Fuel', 'Deviation'), ('Truncation', 'Begin'), ('Truncation', 'End')] + tuples = ['Agent_Prototype', 'Agent_AgentId', 'Agent_ParentId', + 'Finance_ReturnOnDebt', 'Finance_ReturnOnEquity', 'Finance_TaxRate', + 'Finance_DiscountRate', 'Captial_beforePeak', 'Captial_afterPeak', + 'Captial_constructionDuration', 'Captial_Deviation', + 'Captial_OvernightCost', 'Decommissioning_Duration', + 'Decommissioning_OvernightCost', 'OperationMaintenance_FixedCost', + 'OperationMaintenance_VariableCost', + 'OperationMaintenance_Deviation', 'Fuel_Commodity', + 'Fuel_SupplyCost', 'Fuel_WasteFee', 'Fuel_Deviation', + 'Truncation_Begin', 'Truncation_End'] index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) rtn = pd.DataFrame(index=index) dfEntry = series[0].reset_index() agentIndex = dfEntry.reset_index().set_index('AgentId')['index'] rtn = rtn.T - rtn['Agent_Prototype')] = dfEntry['Prototype'] + rtn['Agent_Prototype'] = dfEntry['Prototype'] rtn['Agent_AgentId'] = dfEntry['AgentId'] rtn['Agent_ParentId'] = dfEntry['ParentId'] parametersInput = 'parameters.xml' From ad2f32865e77bbe991a4098e5359cffd6656e545 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 15:34:01 -0500 Subject: [PATCH 10/64] fix syntax --- tests/test_eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index df894400..93d6e095 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -212,7 +212,7 @@ def test_operation_maintenance(): ecoInfo = pd.DataFrame(np.array([ (13, 1, 1, 0) ], dtype=ensure_dt_bytes([ - (('Agent', 'AgentId'), ' Date: Thu, 23 Apr 2020 15:38:22 -0500 Subject: [PATCH 11/64] removing import cyclus --- tests/test_eco_metrics.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 93d6e095..a8536091 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -11,7 +11,6 @@ import pandas as pd from pandas.util.testing import assert_frame_equal -from cymetric import cyclus from cymetric import eco_metrics from cymetric.tools import raw_to_series, ensure_dt_bytes From 33d4336c8de192d63bf5447c62f5926e5b7289a3 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 15:44:12 -0500 Subject: [PATCH 12/64] fix schema --- tests/test_eco_metrics.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index a8536091..fbc45b9d 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -234,7 +234,22 @@ def test_economic_info(): ('Source', 12, 9, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, None, None, None, None, None, None, None, 0, 20), ('Reactor1', 13, 9, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, 1, 1, 0, 'uox', 1, 0, 0, 0, 20) ], dtype=ensure_dt_bytes([ - (('Agent', 'Prototype'), 'O'), (('Agent', 'AgentId'), ' Date: Thu, 23 Apr 2020 15:48:20 -0500 Subject: [PATCH 13/64] fix schema --- tests/test_eco_metrics.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index fbc45b9d..c32e7431 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -48,7 +48,11 @@ def test_capital_cost(): ) ecoInfo = pd.DataFrame(np.array([ ('Reactor1', 13, 10, 5, 10, 0, 1, 0.1) - ], dtype=ensure_dt_bytes([(('Agent', 'Prototype'), 'O'), (('Agent', 'AgentId'), ' Date: Thu, 23 Apr 2020 15:52:05 -0500 Subject: [PATCH 14/64] fix schema --- tests/test_eco_metrics.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index c32e7431..15ea8ce0 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -57,7 +57,10 @@ def test_capital_cost(): s1 = power.set_index(['SimId', 'AgentId', 'Value'])['Time'] s2 = entry.set_index(['AgentId', 'ParentId', 'Spec'])['EnterTime'] s3 = info.set_index(['InitialYear', 'InitialMonth'])['Duration'] - s4 = ecoInfo.set_index([('Agent', 'Prototype'), ('Agent', 'AgentId'), ('Capital', 'beforePeak'), ('Capital', 'afterPeak'), ('Capital', 'constructionDuration'), ('Capital', 'Deviation'), ('Capital', 'OvernightCost')])[('Finance','DiscountRate')] + s4 = ecoInfo.set_index(['Agent_Prototype', 'Agent_AgentId', + 'Captial_beforePeak', 'Captial_afterPeak', + 'Captial_constructionDuration', 'Captial_Deviation', + 'Captial_OvernightCost'), 'Finance_DiscountRate']) series = [s1, s2, s3, s4] obs = eco_metrics.capital_cost.func(series) assert_frame_equal(exp, obs) From f3e83035b7ebfb338db499686f996a54021e7f47 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 15:54:48 -0500 Subject: [PATCH 15/64] fix schema --- tests/test_eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 15ea8ce0..b8e1ce59 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -60,7 +60,7 @@ def test_capital_cost(): s4 = ecoInfo.set_index(['Agent_Prototype', 'Agent_AgentId', 'Captial_beforePeak', 'Captial_afterPeak', 'Captial_constructionDuration', 'Captial_Deviation', - 'Captial_OvernightCost'), 'Finance_DiscountRate']) + 'Captial_OvernightCost', 'Finance_DiscountRate']) series = [s1, s2, s3, s4] obs = eco_metrics.capital_cost.func(series) assert_frame_equal(exp, obs) From c4678a6e64e1fa95df201806edf29b812f34cc14 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 23 Apr 2020 16:01:26 -0500 Subject: [PATCH 16/64] add missing column header --- tests/test_eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index b8e1ce59..464358c9 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -125,7 +125,7 @@ def test_fuel_cost(): 'uox', 9) ], dtype=ensure_dt_bytes([ ('SimId', 'O'), ('TransactionId', ' Date: Thu, 23 Apr 2020 16:05:17 -0500 Subject: [PATCH 17/64] fixing syntax --- tests/test_eco_metrics.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 464358c9..f473b0df 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -125,18 +125,23 @@ def test_fuel_cost(): 'uox', 9) ], dtype=ensure_dt_bytes([ ('SimId', 'O'), ('TransactionId', ' Date: Thu, 23 Apr 2020 16:11:15 -0500 Subject: [PATCH 18/64] fixing syntax --- tests/test_eco_metrics.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index f473b0df..4aca02fb 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -125,7 +125,7 @@ def test_fuel_cost(): 'uox', 9) ], dtype=ensure_dt_bytes([ ('SimId', 'O'), ('TransactionId', ' Date: Fri, 24 Apr 2020 09:32:56 -0500 Subject: [PATCH 19/64] syntax fix --- tests/test_eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 4aca02fb..54eb0480 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -186,7 +186,7 @@ def test_decommissioning_cost(): s1 = power.set_index(['SimId', 'AgentId'])['Value'] s2 = entry.set_index(['EnterTime', 'Lifetime', 'AgentId'])['Spec'] s3 = info.set_index(['SimId', 'InitialYear', 'InitialMonth'])['Duration'] - s4 = ecoInfo.set_index(['Agent_AgentId', 'Decommissioning_Duration'])['Decommissioning_OvernightCost')] + s4 = ecoInfo.set_index(['Agent_AgentId', 'Decommissioning_Duration'])['Decommissioning_OvernightCost'] series = [s1, s2, s3, s4] obs = eco_metrics.decommissioning_cost.func(series) assert_frame_equal(exp, obs) From 22952c017aae1f400847855171136dab94321aab Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 24 Apr 2020 10:00:32 -0500 Subject: [PATCH 20/64] syntax fix --- tests/test_eco_metrics.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 54eb0480..85e3c109 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -224,10 +224,14 @@ def test_operation_maintenance(): ecoInfo = pd.DataFrame(np.array([ (13, 1, 1, 0) ], dtype=ensure_dt_bytes([ - (('Agent', 'AgentId'), ' Date: Fri, 24 Apr 2020 10:21:32 -0500 Subject: [PATCH 21/64] extend table --- tests/test_eco_metrics.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 85e3c109..b4519d24 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -246,10 +246,11 @@ def test_economic_info(): ('Payment',' Date: Fri, 24 Apr 2020 10:27:21 -0500 Subject: [PATCH 22/64] replacing None per 0 --- tests/test_eco_metrics.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index b4519d24..3fed1fe2 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -246,10 +246,10 @@ def test_economic_info(): ('Payment',' Date: Fri, 24 Apr 2020 11:09:08 -0500 Subject: [PATCH 23/64] syntax --- tests/test_eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 3fed1fe2..4ce72e4e 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -269,7 +269,7 @@ def test_economic_info(): ('Fuel_WasteFee', ' Date: Fri, 24 Apr 2020 11:37:15 -0500 Subject: [PATCH 24/64] fixing table --- tests/test_eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 4ce72e4e..e9fa4688 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -250,7 +250,7 @@ def test_economic_info(): 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20), ('Institution1', 9, 8, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20), ('Source', 12, 9, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20), - ('Reactor1', 13, 9, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, 1, 1, 0, 'uox', 1, 0, 0, 0, 0, 0, 0, 20) + ('Reactor1', 13, 9, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, 1, 1, 0, 0, 0, 'uox', 1, 0, 0, 0, 0, 20) ], dtype=ensure_dt_bytes([ ('Agent_Prototype', 'O'), ('Agent_AgentId', ' Date: Tue, 28 Apr 2020 14:17:28 -0500 Subject: [PATCH 25/64] working simplified version of capital_cost --- cymetric/eco_metrics.py | 2327 +++++++++++++++++++------------------ cymetric/eco_tools.py | 146 +-- tests/test_eco_metrics.py | 41 +- 3 files changed, 1256 insertions(+), 1258 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 666d1ac8..fd30b944 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -33,55 +33,57 @@ ## The actual metrics ## -_ccdeps = [('TimeSeriesPower', ('SimId', 'AgentId', 'Value'), 'Time'), ('AgentEntry', ('AgentId', 'ParentId', 'Spec'), 'EnterTime'), ('Info', ('InitialYear', 'InitialMonth'), 'Duration'), ('EconomicInfo', (('Agent', 'Prototype'), ('Agent', 'AgentId'), ('Capital', 'beforePeak'), ('Capital', 'afterPeak'), ('Capital', 'constructionDuration'), ('Capital', 'Deviation'), ('Capital', 'OvernightCost')), ('Finance','DiscountRate'))] +_ccdeps = ['TimeSeriesPower', 'AgentEntry', 'Info', 'EconomicInfo'] + +_ccschema = [ + ('SimId', ts.UUID), + ('AgentId', ts.INT), + ('Time', ts.INT), + ('Payment', ts.DOUBLE)] -_ccschema = [('SimId', ts.UUID), ('AgentId', ts.INT), - ('Time', ts.INT), ('Payment', ts.DOUBLE)] @metric(name='CapitalCost', depends=_ccdeps, schema=_ccschema) -def capital_cost(series): +def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): """The CapitalCost metric gives the cash flows at each time step corresponding to the reactors construction costs. """ - dfPower = series[0].reset_index() - dfEntry = series[1].reset_index() - dfInfo = series[2].reset_index() - dfEcoInfo = series[3].reset_index() - tuples = (('Agent', 'Prototype'), ('Agent', 'AgentId'), ('Capital', 'beforePeak'), ('Capital', 'afterPeak'), ('Capital', 'constructionDuration'), ('Capital', 'Deviation'), ('Capital', 'OvernightCost'), ('Finance','DiscountRate')) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) - dfEcoInfo.columns = index - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) simDuration = dfInfo['Duration'].iloc[0] dfEntry = pd.DataFrame([dfEntry.EnterTime, dfEntry.AgentId]).transpose() - dfEntry = dfEntry.set_index(['AgentId']) - agentIds = dfEcoInfo.index + #dfEntry = dfEntry.set_index(['AgentId']) rtn = pd.DataFrame() - for id in agentIds: - tmp = dfEcoInfo.loc[id].copy() - if isinstance(tmp, pd.DataFrame): - tmp = tmp.iloc[0] - if isreactor(dfPower, id): - deviation = dfEcoInfo.loc[id, ('Capital', 'Deviation')] - deviation = deviation * np.random.randn(1) - deviation = int(np.around(deviation)) - beforePeak = int(tmp.loc[('Capital', 'beforePeak')] + deviation) - afterPeak = int(tmp.loc[('Capital', 'afterPeak')]) - constructionDuration = int(tmp.loc[('Capital', 'constructionDuration')] + deviation) - overnightCost = tmp.loc[('Capital', 'OvernightCost')] - cashFlowShape = capital_shape(beforePeak, afterPeak) - powerCapacity = max(dfPower[dfPower.AgentId==id]['Value']) - discountRate = tmp.loc[('Finance','DiscountRate')] - cashFlow = np.around(cashFlowShape * overnightCost * powerCapacity, 4) - cashFlow *= ((1 + discountRate) ** math.ceil((beforePeak + afterPeak) / 12) - 1) / (discountRate * math.ceil((beforePeak + afterPeak) / 12)) - tmp = pd.DataFrame({'AgentId': id, 'Time': pd.Series(list(range(beforePeak + afterPeak + 1))) + dfEntry.EnterTime[id] - constructionDuration, 'Payment' : cashFlow}) - rtn = pd.concat([rtn, tmp], ignore_index=True) + for index, eco_row in dfEcoInfo.iterrows(): + id = eco_row['AgentId'] + if isreactor(dfPower, id): + deviation = eco_row['Capital_Deviation'] * np.random.randn(1) + deviation = int(np.around(deviation)) + + beforePeak = int(eco_row['Capital_beforePeak'] + deviation) + afterPeak = int(eco_row['Capital_afterPeak']) + + entry_time = dfEntry[dfEntry['AgentId'] == id].EnterTime.values[0] + constructionDuration = int( + eco_row['Capital_constructionDuration'] + deviation) + powerCapacity = max(dfPower[dfPower.AgentId == id]['Value']) + + overnightCost = eco_row['Capital_OvernightCost'] + cashFlowShape = capital_shape(beforePeak, afterPeak) + discountRate = eco_row['Finance_DiscountRate'] + cashFlow = np.around( + cashFlowShape * overnightCost * powerCapacity, 4) + cashFlow *= ((1 + discountRate) ** math.ceil((beforePeak + afterPeak) / 12) - + 1) / (discountRate * math.ceil((beforePeak + afterPeak) / 12)) + + tmp = pd.DataFrame(data={'AgentId': id, + 'Time': pd.Series(list(range(beforePeak + afterPeak + 1))) + + entry_time - constructionDuration, + 'Payment': cashFlow}, + columns=['AgentId', 'Time', 'Payment']) + rtn = pd.concat([rtn, tmp], ignore_index=False) + rtn['SimId'] = dfPower['SimId'].iloc[0] - subset = rtn.columns.tolist() - subset = subset[3:] + subset[:1] + subset[2:3] + subset[1:2] - rtn = rtn[subset] rtn = rtn[rtn['Time'].apply(lambda x: x >= 0 and x < simDuration)] rtn = rtn.reset_index() - del rtn['index'] - return rtn + return rtn[['SimId', 'AgentId', 'Time', 'Payment']] + del _ccdeps, _ccschema @@ -110,22 +112,22 @@ def fuel_cost(series): dfTransactions.loc[:, 'Payment'] = dfTransactions.loc[:, 'Payment'].fillna(0) dfTransactions['Tmp'] = pd.Series() for agentId in dfEcoInfo.index: - tmpTrans = dfTransactions[dfTransactions.ReceiverId==agentId] - if isinstance(dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')], str): - commod = dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')] - deviation = dfEcoInfo.loc[agentId, ('Fuel', 'Deviation')] - tmpTrans2 = tmpTrans[tmpTrans.Commodity==commod] - deviation = deviation * np.random.randn(1) - price = deviation + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'SupplyCost')] + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'WasteFee')] - dfTransactions.loc[:, 'Tmp'] = tmpTrans2.loc[:, 'Quantity'] * price - elif isinstance(dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')], pd.Series): - for commod in dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')]: - deviation = dfEcoInfo.loc[id, ('Fuel', 'Deviation')] - deviation = deviation * np.random.randn(1) - price = deviation + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'SupplyCost')] + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'WasteFee')] - tmpTrans2 = tmpTrans[tmpTrans.Commodity==commod] - dfTransactions.loc[:, 'Tmp'] = tmpTrans2.loc[:, 'Quantity'] * price - dfTransactions.loc[:, 'Payment'] += dfTransactions.loc[:, 'Tmp'].fillna(0) + tmpTrans = dfTransactions[dfTransactions.ReceiverId==agentId] + if isinstance(dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')], str): + commod = dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')] + deviation = dfEcoInfo.loc[agentId, ('Fuel', 'Deviation')] + tmpTrans2 = tmpTrans[tmpTrans.Commodity==commod] + deviation = deviation * np.random.randn(1) + price = deviation + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'SupplyCost')] + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'WasteFee')] + dfTransactions.loc[:, 'Tmp'] = tmpTrans2.loc[:, 'Quantity'] * price + elif isinstance(dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')], pd.Series): + for commod in dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')]: + deviation = dfEcoInfo.loc[id, ('Fuel', 'Deviation')] + deviation = deviation * np.random.randn(1) + price = deviation + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'SupplyCost')] + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'WasteFee')] + tmpTrans2 = tmpTrans[tmpTrans.Commodity==commod] + dfTransactions.loc[:, 'Tmp'] = tmpTrans2.loc[:, 'Quantity'] * price + dfTransactions.loc[:, 'Payment'] += dfTransactions.loc[:, 'Tmp'].fillna(0) del dfTransactions['Quantity'] del dfTransactions['Tmp'] rtn = dfTransactions.reset_index() @@ -139,8 +141,8 @@ def fuel_cost(series): _dcdeps = [ ('TimeSeriesPower', ('SimId', 'AgentId'), 'Value'), - ('AgentEntry', ('EnterTime', 'Lifetime', 'AgentId'), 'Spec'), - ('Info', ('InitialYear', 'InitialMonth'), 'Duration'), ('EconomicInfo', (('Agent', 'AgentId'), ('Decommissioning', 'Duration')), ('Decommissioning', 'OvernightCost'))] + ('AgentEntry', ('EnterTime', 'Lifetime', 'AgentId'), 'Spec'), + ('Info', ('InitialYear', 'InitialMonth'), 'Duration'), ('EconomicInfo', (('Agent', 'AgentId'), ('Decommissioning', 'Duration')), ('Decommissioning', 'OvernightCost'))] _dcschema = [('SimId', ts.UUID), ('AgentId', ts.INT), ('Payment', ts.DOUBLE), ('Time', ts.INT)] @@ -150,7 +152,7 @@ def decommissioning_cost(series): """The Decommissioning cost metric gives the cash flows at each time step corresponding to the reactors decommissioning. """ if series[0].empty: - return pd.DataFrame() + return pd.DataFrame() dfPower = series[0].reset_index() dfPower = dfPower[dfPower['Value'].apply(lambda x: x > 0)] dfEntry = series[1].reset_index() @@ -166,17 +168,17 @@ def decommissioning_cost(series): reactorsId = dfEntry[dfEntry['Spec'].apply(lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() rtn = pd.DataFrame() for id in reactorsId: - tmp = dfEcoInfo.loc[id].copy() - if isinstance(tmp,pd.DataFrame): - tmp = tmp.iloc[0] - duration = int(tmp.loc[('Decommissioning', 'Duration')]) - overnightCost = tmp.loc[('Decommissioning', 'OvernightCost')] - cashFlowShape = capital_shape(duration - duration // 2, duration // 2) - powerCapacity = dfPower[dfPower.AgentId==id]['Value'].iloc[0] - cashFlow = cashFlowShape * powerCapacity * overnightCost - entryTime = dfEntry[dfEntry.AgentId==id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId==id]['Lifetime'].iloc[0] - rtn = pd.concat([rtn,pd.DataFrame({'AgentId': id, 'Time': list(range(lifetime + entryTime, lifetime + entryTime + duration + 1)), 'Payment': cashFlow})], ignore_index=True) + tmp = dfEcoInfo.loc[id].copy() + if isinstance(tmp,pd.DataFrame): + tmp = tmp.iloc[0] + duration = int(tmp.loc[('Decommissioning', 'Duration')]) + overnightCost = tmp.loc[('Decommissioning', 'OvernightCost')] + cashFlowShape = capital_shape(duration - duration // 2, duration // 2) + powerCapacity = dfPower[dfPower.AgentId==id]['Value'].iloc[0] + cashFlow = cashFlowShape * powerCapacity * overnightCost + entryTime = dfEntry[dfEntry.AgentId==id]['EnterTime'].iloc[0] + lifetime = dfEntry[dfEntry.AgentId==id]['Lifetime'].iloc[0] + rtn = pd.concat([rtn,pd.DataFrame({'AgentId': id, 'Time': list(range(lifetime + entryTime, lifetime + entryTime + duration + 1)), 'Payment': cashFlow})], ignore_index=True) rtn['SimId'] = dfPower['SimId'].iloc[0] subset = rtn.columns.tolist() subset = subset[-1:]+subset[:-1] @@ -186,37 +188,42 @@ def decommissioning_cost(series): del _dcdeps, _dcschema -_omdeps = [('TimeSeriesPower', ('SimId', 'AgentId', 'Time'), 'Value'), ('EconomicInfo', (('Agent', 'AgentId'), ('OperationMaintenance', 'FixedCost'), ('OperationMaintenance', 'VariableCost')), ('OperationMaintenance', 'Deviation'))] +_omdeps = ['TimeSeriesPower', 'EconomicInfo'] _omschema = [('SimId', ts.UUID), ('AgentId', ts.INT), ('Time', ts.INT), ('Payment', ts.DOUBLE)] @metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) -def operation_maintenance(series): +def operation_maintenance(s1, s2): """The OperationMaintenance metric gives the cash flows at each time step corresponding to the reactor operations and maintenance costs. """ - rtn = series[0].reset_index() - dfEcoInfo = series[1].reset_index() - tuples = (('Agent', 'AgentId'), ('OperationMaintenance', 'FixedCost'), ('OperationMaintenance', 'VariableCost'), ('OperationMaintenance', 'Deviation')) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) - dfEcoInfo.columns = index - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) + rtn = s1 + dfEcoInfo = s2 + index = ['AgentId', 'FixedCost', + 'VariableCost', + 'Deviation'] + #index = pd.MultiIndex.from_tuples(tuples) + #dfEcoInfo.columns = index + dfEcoInfo = dfEcoInfo.set_index('AgentId') + print(rtn) + print(dfEcoInfo) + dfEcoInfo = dfEcoInfo rtn['Payment'] = 0 rtn['tmp'] = 0 for id in dfEcoInfo.index: - if isreactor(rtn, id): - powerGenerated = rtn[rtn.AgentId==id].loc[:,'Value'] - powerCapacity = max(powerGenerated) - powerGenerated *= 8760 / 12 - tmp = dfEcoInfo.loc[id].copy() - if isinstance(tmp,pd.DataFrame): - tmp = tmp.iloc[0] - deviation = tmp.loc[('OperationMaintenance', 'Deviation')] - deviation *= np.random.randn(1) - fixedOM = tmp.loc[('OperationMaintenance', 'FixedCost')] + deviation - variableOM = tmp.loc[('OperationMaintenance', 'VariableCost')] + deviation - rtn['tmp'] = powerGenerated * variableOM + powerCapacity * fixedOM - rtn.loc[:, 'Payment'] += rtn.loc[:, 'tmp'].fillna(0) + if isreactor(rtn, id): + powerGenerated = rtn[rtn.AgentId==id].loc[:,'Value'] + powerCapacity = max(powerGenerated) + powerGenerated *= 8760 / 12 + tmp = dfEcoInfo.loc[id].copy() + if isinstance(tmp,pd.DataFrame): + tmp = tmp.iloc[0] + deviation = tmp.loc['Deviation'] + deviation *= np.random.randn(1) + fixedOM = tmp.loc['FixedCost'] + deviation + variableOM = tmp.loc['VariableCost'] + deviation + rtn['tmp'] = powerGenerated * variableOM + powerCapacity * fixedOM + rtn.loc[:, 'Payment'] += rtn.loc[:, 'tmp'].fillna(0) rtn = rtn.reset_index() del rtn['Value'], rtn['index'], rtn['tmp'] return rtn @@ -240,7 +247,7 @@ def operation_maintenance(series): ('FuelCommodity', ts.STRING), ('Fuel_SupplyCost', ts.DOUBLE), ('Fuel_WasteFee', ts.DOUBLE), ('Fuel_Deviation', ts.DOUBLE), ('Truncation_Begin', ts.INT), ('Truncation_End', ts.INT)] - + @metric(name='EconomicInfo', depends=_eideps, schema=_eischema) def economic_info(series): """The EconomicInfo metric stores all economic data needed to calculate the economic metrics. These economic parameters are originally written in 'parameters.xml'. @@ -271,345 +278,345 @@ def economic_info(series): rtn['Truncation_End'] = int(truncation.find('simulation_end').text) finance = root.find('finance') if not finance == None: - rtn.loc[:, 'Finance_TaxRate'] = float(finance.find('tax_rate').text) - rtn.loc[:, 'Finance_ReturnOnDebt'] = float(finance.find('return_on_debt').text) - rtn.loc[:, 'Finance_ReturnOnEquity'] = float(finance.find('return_on_equity').text) - rtn.loc[:, 'Finance_DiscountRate'] = float(finance.find('discount_rate').text) + rtn.loc[:, 'Finance_TaxRate'] = float(finance.find('tax_rate').text) + rtn.loc[:, 'Finance_ReturnOnDebt'] = float(finance.find('return_on_debt').text) + rtn.loc[:, 'Finance_ReturnOnEquity'] = float(finance.find('return_on_equity').text) + rtn.loc[:, 'Finance_DiscountRate'] = float(finance.find('discount_rate').text) capital = root.find('capital') if not capital == None: - rtn.loc[:, 'Capital_beforePeak'] = int(capital.find('beforePeak').text) - rtn.loc[:, 'Capital_afterPeak'] = int(capital.find('afterPeak').text) - rtn.loc[:, 'Capital_constructionDuration'] = int(capital.find('constructionDuration').text) - rtn.loc[:, 'Capital_Deviation'] = float(capital.find('deviation').text) - rtn.loc[:, 'Capital_OvernightCost'] = float(capital.find('overnight_cost').text) + rtn.loc[:, 'Capital_beforePeak'] = int(capital.find('beforePeak').text) + rtn.loc[:, 'Capital_afterPeak'] = int(capital.find('afterPeak').text) + rtn.loc[:, 'Capital_constructionDuration'] = int(capital.find('constructionDuration').text) + rtn.loc[:, 'Capital_Deviation'] = float(capital.find('deviation').text) + rtn.loc[:, 'Capital_OvernightCost'] = float(capital.find('overnight_cost').text) decommissioning = root.find('decommissioning') if not decommissioning == None: - rtn.loc[:, 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) - rtn.loc[:, 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) + rtn.loc[:, 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) + rtn.loc[:, 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) operation_maintenance = root.find('operation_maintenance') if not operation_maintenance == None: - rtn.loc[:, 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) - rtn.loc[:, 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) - rtn.loc[:, 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) + rtn.loc[:, 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) + rtn.loc[:, 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) + rtn.loc[:, 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) fuel = root.find('fuel') indexCopy = rtn.index.copy() if not fuel == None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - for j in indexCopy: - if np.isnan(rtn.loc[j, 'Fuel_SupplyCost']): - rtn.loc[j, 'Fuel_Commodity'] = name - rtn.loc[j, 'Fuel_SupplyCost'] = supply - rtn.loc[j, 'Fuel_WasteFee'] = waste - rtn.loc[j, 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[j] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation + for type in fuel.findall('type'): + supply = float(type.find('supply_cost').text) + waste = float(type.find('waste_fee').text) + name = type.find('name').text + deviation = float(type.find('deviation').text) + for j in indexCopy: + if np.isnan(rtn.loc[j, 'Fuel_SupplyCost']): + rtn.loc[j, 'Fuel_Commodity'] = name + rtn.loc[j, 'Fuel_SupplyCost'] = supply + rtn.loc[j, 'Fuel_WasteFee'] = waste + rtn.loc[j, 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[j] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation for region in root.findall('region'): - idRegion = int(region.find('id').text) - finance = region.find('finance') - if not finance == None: - returnOnDebt = float(finance.find('return_on_debt').text) - returnOnEquity = float(finance.find('return_on_equity').text) - taxRate = float(finance.find('tax_rate').text) - discountRate = float(finance.find('discount_rate').text) - rtn.loc[agentIndex[idRegion], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idRegion], 'Finance_DiscountRate'] = discountRate - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate - capital = region.find('capital') - if capital is not None: - beforePeak = int(capital.find('beforePeak').text) - afterPeak = int(capital.find('afterPeak').text) - constructionDuration = int(capital.find('constructionDuration').text) - deviation = float(capital.find('deviation').text) - overnightCost = float(capital.find('overnight_cost').text) - rtn.loc[agentIndex[idRegion], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idRegion], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idRegion], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idRegion], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idRegion], 'Captial_OvernightCost'] = overnightCost - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost - decommissioning = region.find('decommissioning') - if decommissioning is not None: - duration = int(decommissioning.find('duration').text) - overnightCost = float(decommissioning.find('overnight_cost').text) - rtn.loc[agentIndex[idRegion], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idRegion], 'Decommissioning_OvernightCost'] = overnightCost - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost - operation_maintenance = region.find('operation_maintenance') - if operation_maintenance is not None: - fixed = float(operation_maintenance.find('fixed').text) - variable = float(operation_maintenance.find('variable').text) - deviation = float(operation_maintenance.find('deviation').text) - rtn.loc[agentIndex[idRegion], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idRegion], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idRegion], 'OperationMaintenance_Deviation'] = deviation - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - fuel = region.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idRegion], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idRegion], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idRegion], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idRegion]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for institution in region.findall('institution'): - idInstitution = int(institution.find('id').text) - finance = institution.find('finance') - if finance is not None: - returnOnDebt = float(finance.find('return_on_debt').text) - returnOnEquity = float(finance.find('return_on_equity').text) - taxRate = float(finance.find('tax_rate').text) - discountRate = float(finance.find('discount_rate').text) - rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idInstitution],'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate - capital = institution.find('capital') - if capital is not None: - beforePeak = int(capital.find('beforePeak').text) - afterPeak = int(capital.find('afterPeak').text) - constructionDuration = int(capital.find('constructionDuration').text) - deviation = float(capital.find('deviation').text) - overnightCost = float(capital.find('overnight_cost').text) - rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost - decommissioning = institution.find('decommissioning') - if decommissioning is not None: - duration = int(decommissioning.find('duration').text) - overnightCost = float(decommissioning.find('overnight_cost').text) - rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost - operation_maintenance = institution.find('operation_maintenance') - if operation_maintenance is not None: - fixed = float(operation_maintenance.find('fixed').text) - variable = float(operation_maintenance.find('variable').text) - deviation = float(operation_maintenance.find('deviation').text) - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - fuel = institution.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for prototype in institution.findall('prototype'): - name = prototype.find('name').text - tmp = dfEntry[dfEntry.ParentId==idInstitution] - facilityIdList = tmp[tmp.Prototype==name].loc[:,'AgentId'].tolist() - capital = prototype.find('capital') - if capital is not None: - beforePeak = int(capital.find('beforePeak').text) - afterPeak = int(capital.find('afterPeak').text) - constructionDuration = int(capital.find('constructionDuration').text) - deviation = float(capital.find('deviation').text) - overnight = float(capital.find('overnight_cost').text) - for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnight - operation_maintenance = prototype.find('operation_maintenance') - if operation_maintenance is not None: - fixed = float(operation_maintenance.find('fixed').text) - variable = float(operation_maintenance.find('variable').text) - deviation = float(operation_maintenance.find('deviation').text) - for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - fuel = prototype.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - for idFacility in facilityIdList: - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - decommissioning = prototype.find('decommissioning') - if decommissioning is not None: - duration = int(decommissioning.find('duration').text) - overnight = float(decommissioning.find('overnight_cost').text) - for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnight - for facility in prototype.findall('facility'): - idFacility = int(facility.find('id').text) - capital = facility.find('capital') - if capital is not None: - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = int(capital.find('beforePeak').text) - rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = int(capital.find('afterPeak').text) - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = int(capital.find('constructionDuration').text) - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = float(capital.find('deviation').text) - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = float(capital.find('overnight_cost').text) - operation_maintenance = facility.find('operation_maintenance') - if operation_maintenance is not None: - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) - fuel = facility.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - decommissioning = facility.find('decommissioning') - if decommissioning is not None: - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) + idRegion = int(region.find('id').text) + finance = region.find('finance') + if not finance == None: + returnOnDebt = float(finance.find('return_on_debt').text) + returnOnEquity = float(finance.find('return_on_equity').text) + taxRate = float(finance.find('tax_rate').text) + discountRate = float(finance.find('discount_rate').text) + rtn.loc[agentIndex[idRegion], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idRegion], 'Finance_DiscountRate'] = discountRate + for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate + capital = region.find('capital') + if capital is not None: + beforePeak = int(capital.find('beforePeak').text) + afterPeak = int(capital.find('afterPeak').text) + constructionDuration = int(capital.find('constructionDuration').text) + deviation = float(capital.find('deviation').text) + overnightCost = float(capital.find('overnight_cost').text) + rtn.loc[agentIndex[idRegion], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idRegion], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idRegion], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idRegion], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idRegion], 'Captial_OvernightCost'] = overnightCost + for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost + decommissioning = region.find('decommissioning') + if decommissioning is not None: + duration = int(decommissioning.find('duration').text) + overnightCost = float(decommissioning.find('overnight_cost').text) + rtn.loc[agentIndex[idRegion], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idRegion], 'Decommissioning_OvernightCost'] = overnightCost + for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost + operation_maintenance = region.find('operation_maintenance') + if operation_maintenance is not None: + fixed = float(operation_maintenance.find('fixed').text) + variable = float(operation_maintenance.find('variable').text) + deviation = float(operation_maintenance.find('deviation').text) + rtn.loc[agentIndex[idRegion], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idRegion], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idRegion], 'OperationMaintenance_Deviation'] = deviation + for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation + fuel = region.find('fuel') + if fuel is not None: + for type in fuel.findall('type'): + supply = float(type.find('supply_cost').text) + waste = float(type.find('waste_fee').text) + name = type.find('name').text + deviation = float(type.find('deviation').text) + if np.isnan(rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idRegion], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idRegion], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idRegion], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idRegion]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + for institution in region.findall('institution'): + idInstitution = int(institution.find('id').text) + finance = institution.find('finance') + if finance is not None: + returnOnDebt = float(finance.find('return_on_debt').text) + returnOnEquity = float(finance.find('return_on_equity').text) + taxRate = float(finance.find('tax_rate').text) + discountRate = float(finance.find('discount_rate').text) + rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idInstitution],'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt + rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity + rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate + capital = institution.find('capital') + if capital is not None: + beforePeak = int(capital.find('beforePeak').text) + afterPeak = int(capital.find('afterPeak').text) + constructionDuration = int(capital.find('constructionDuration').text) + deviation = float(capital.find('deviation').text) + overnightCost = float(capital.find('overnight_cost').text) + rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost + decommissioning = institution.find('decommissioning') + if decommissioning is not None: + duration = int(decommissioning.find('duration').text) + overnightCost = float(decommissioning.find('overnight_cost').text) + rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost + operation_maintenance = institution.find('operation_maintenance') + if operation_maintenance is not None: + fixed = float(operation_maintenance.find('fixed').text) + variable = float(operation_maintenance.find('variable').text) + deviation = float(operation_maintenance.find('deviation').text) + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation + fuel = institution.find('fuel') + if fuel is not None: + for type in fuel.findall('type'): + supply = float(type.find('supply_cost').text) + waste = float(type.find('waste_fee').text) + name = type.find('name').text + deviation = float(type.find('deviation').text) + if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + for prototype in institution.findall('prototype'): + name = prototype.find('name').text + tmp = dfEntry[dfEntry.ParentId==idInstitution] + facilityIdList = tmp[tmp.Prototype==name].loc[:,'AgentId'].tolist() + capital = prototype.find('capital') + if capital is not None: + beforePeak = int(capital.find('beforePeak').text) + afterPeak = int(capital.find('afterPeak').text) + constructionDuration = int(capital.find('constructionDuration').text) + deviation = float(capital.find('deviation').text) + overnight = float(capital.find('overnight_cost').text) + for idFacility in facilityIdList: + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnight + operation_maintenance = prototype.find('operation_maintenance') + if operation_maintenance is not None: + fixed = float(operation_maintenance.find('fixed').text) + variable = float(operation_maintenance.find('variable').text) + deviation = float(operation_maintenance.find('deviation').text) + for idFacility in facilityIdList: + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation + fuel = prototype.find('fuel') + if fuel is not None: + for type in fuel.findall('type'): + supply = float(type.find('supply_cost').text) + waste = float(type.find('waste_fee').text) + name = type.find('name').text + deviation = float(type.find('deviation').text) + for idFacility in facilityIdList: + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + decommissioning = prototype.find('decommissioning') + if decommissioning is not None: + duration = int(decommissioning.find('duration').text) + overnight = float(decommissioning.find('overnight_cost').text) + for idFacility in facilityIdList: + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnight + for facility in prototype.findall('facility'): + idFacility = int(facility.find('id').text) + capital = facility.find('capital') + if capital is not None: + rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = int(capital.find('beforePeak').text) + rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = int(capital.find('afterPeak').text) + rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = int(capital.find('constructionDuration').text) + rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = float(capital.find('deviation').text) + rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = float(capital.find('overnight_cost').text) + operation_maintenance = facility.find('operation_maintenance') + if operation_maintenance is not None: + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) + rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) + fuel = facility.find('fuel') + if fuel is not None: + for type in fuel.findall('type'): + supply = float(type.find('supply_cost').text) + waste = float(type.find('waste_fee').text) + name = type.find('name').text + deviation = float(type.find('deviation').text) + if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + else: + indice = rtn.index.size + rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + rtn.loc[indice, 'Fuel_Commodity'] = name + rtn.loc[indice, 'Fuel_SupplyCost'] = supply + rtn.loc[indice, 'Fuel_WasteFee'] = waste + rtn.loc[indice, 'Fuel_Deviation'] = deviation + decommissioning = facility.find('decommissioning') + if decommissioning is not None: + rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) + rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) return rtn - + del _eideps, _eischema @@ -657,17 +664,17 @@ def annual_costs(outputDb, reactorId, capital=True): costs = costs.fillna(0) costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear if not capital: - del costs['Capital'] + del costs['Capital'] costs = costs.groupby('Year').sum() return costs def annual_costs_present_value(outputDb, reactorId, capital=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION - """ - costs = annual_costs(outputDb, reactorId, capital) - actualization = actualization_vector(len(costs)) - actualization.index = costs.index - return costs.apply(lambda x : x * actualization) + """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """ + costs = annual_costs(outputDb, reactorId, capital) + actualization = actualization_vector(len(costs)) + actualization.index = costs.index + return costs.apply(lambda x : x * actualization) def average_cost(outputDb, reactorId, capital=True): """Input : sqlite output database, reactor's AgentId @@ -680,781 +687,781 @@ def average_cost(outputDb, reactorId, capital=True): return annual_costs(outputDb, reactorId, capital).sum().sum() / powerGenerated def benefit(outputDb, reactorId): - """Input : sqlite output database and reactor agent id - Output : cumulative sum of actualized income and expense (= - expenditures + income) - """ - costs = - annual_costs(outputDb, reactorId).sum(axis=1) - powerGenerated = power_generated(outputDb, reactorId) * lcoe(outputDb, reactorId) - rtn = pd.concat([costs, powerGenerated], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn + """Input : sqlite output database and reactor agent id + Output : cumulative sum of actualized income and expense (= - expenditures + income) + """ + costs = - annual_costs(outputDb, reactorId).sum(axis=1) + powerGenerated = power_generated(outputDb, reactorId) * lcoe(outputDb, reactorId) + rtn = pd.concat([costs, powerGenerated], axis=1).fillna(0) + rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() + return rtn def lcoe(outputDb, reactorId, capital=True): - """Input : sqlite output database and reactor agent id - Output : Value corresponding to Levelized Cost of Electricity ($/MWh) - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfEcoInfo = evaler.eval('EconomicInfo') - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - discountRate = dfEcoInfo.loc[reactorId, ('Finance', 'DiscountRate')] - annualCosts = annual_costs(outputDb, reactorId, capital) - powerGenerated = power_generated(outputDb, reactorId) - actualization = actualization_vector(powerGenerated.size, discountRate) - actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) - + """Input : sqlite output database and reactor agent id + Output : Value corresponding to Levelized Cost of Electricity ($/MWh) + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfEcoInfo = evaler.eval('EconomicInfo') + dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) + discountRate = dfEcoInfo.loc[reactorId, ('Finance', 'DiscountRate')] + annualCosts = annual_costs(outputDb, reactorId, capital) + powerGenerated = power_generated(outputDb, reactorId) + actualization = actualization_vector(powerGenerated.size, discountRate) + actualization.index = powerGenerated.index.copy() + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) + def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): - """Input : sqlite output database, reactor id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEcoInfo.loc[:, ('Truncation', 'End')] - costs = annual_costs(outputDb, reactorId, capital) - costs = costs.sum(axis=1) - power = power_generated(outputDb, reactorId) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear # year instead of months - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = rtn['Ratio'] * actualization - return rtn - + """Input : sqlite output database, reactor id, time window (t0, period) + Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo.loc[:, ('Truncation', 'Begin')] + simulationEnd = dfEcoInfo.loc[:, ('Truncation', 'End')] + costs = annual_costs(outputDb, reactorId, capital) + costs = costs.sum(axis=1) + power = power_generated(outputDb, reactorId) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear # year instead of months + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for i in range(simulationBegin + t0, simulationBegin + t0 + period): + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + for j in range(simulationBegin + 1, simulationEnd): + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = rtn['Ratio'] * actualization + return rtn + def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): - """Just for tests : another way to calculate the period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - costs = annual_costs(outputDb, institutionId, capital) - costs = costs.sum(axis=1) - power = power_generated(outputDb, institutionId) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEcoInfo.loc[:, ('Truncation', 'End')] - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - #tmp['WasteManagement'][j] = pd.Series() - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - return rtn + """Just for tests : another way to calculate the period costs + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + costs = annual_costs(outputDb, institutionId, capital) + costs = costs.sum(axis=1) + power = power_generated(outputDb, institutionId) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo.loc[:, ('Truncation', 'Begin')] + simulationEnd = dfEcoInfo.loc[:, ('Truncation', 'End')] + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for j in range(simulationBegin, simulationEnd + 1): + for i in range(j + t0, j + t0 + period): + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) + #tmp['WasteManagement'][j] = pd.Series() + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + return rtn def power_generated(outputDb, reactorId): - """Input : sqlite output database and reactor agent id - Output : Electricity generated in MWh every year - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfPower = evaler.eval('TimeSeriesPower').reset_index() - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfPower = dfPower[dfPower['AgentId']==reactorId].copy() - dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear - dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, initialYear + (initialMonth + duration) // 12 + 1))) - return rtn.fillna(0) + """Input : sqlite output database and reactor agent id + Output : Electricity generated in MWh every year + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfPower = evaler.eval('TimeSeriesPower').reset_index() + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfPower = dfPower[dfPower['AgentId']==reactorId].copy() + dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear + dfPower = dfPower.groupby('Year').sum() + rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, initialYear + (initialMonth + duration) // 12 + 1))) + return rtn.fillna(0) # Institution level def institution_annual_costs(outputDb, institutionId, capital=True, truncate=True): - """Input : sqlite output database and institution's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. - Output : total reactor costs per year over its lifetime at the institution level. - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId==institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x= beginYear)] - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum() - return costs - + """Input : sqlite output database and institution's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. + Output : total reactor costs per year over its lifetime at the institution level. + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + dfEntry = evaler.eval('AgentEntry').reset_index() + dfEntry = dfEntry[dfEntry.ParentId==institutionId] + dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x= beginYear)] + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum() + return costs + def institution_annual_costs_present_value(outputDb, reactorId, capital=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION - """ - costs = institution_annual_costs(outputDb, institutionId, capital) - actualization = actualization_vector(len(costs)) - actualization.index = costs.index - return costs.apply(lambda x : x * actualization) - + """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """ + costs = institution_annual_costs(outputDb, institutionId, capital) + actualization = actualization_vector(len(costs)) + actualization.index = costs.index + return costs.apply(lambda x : x * actualization) + def institution_benefit(outputDb, institutionId): - """Input : sqlite output database and institution agent id - Output : cumulative sum of income and expense (= - expenditures + income) - """ - costs = - institution_annual_costs(outputDb, institutionId).sum(axis=1) - power_gen = institution_power_generated(outputDb, institutionId) * institution_average_lcoe(outputDb, institutionId)['Average LCOE'] - rtn = pd.concat([costs, power_gen], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn - + """Input : sqlite output database and institution agent id + Output : cumulative sum of income and expense (= - expenditures + income) + """ + costs = - institution_annual_costs(outputDb, institutionId).sum(axis=1) + power_gen = institution_power_generated(outputDb, institutionId) * institution_average_lcoe(outputDb, institutionId)['Average LCOE'] + rtn = pd.concat([costs, power_gen], axis=1).fillna(0) + rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() + return rtn + def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=True): - """Input : sqlite output database, institution id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() - simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] - costs = institution_annual_costs(outputDb, institutionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = institution_power_generated(outputDb, institutionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = rtn['Ratio'] * actualization - return rtn - + """Input : sqlite output database, institution id, time window (t0, period) + Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() + simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] + simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] + costs = institution_annual_costs(outputDb, institutionId, capital, truncate=False) + costs = costs.sum(axis=1) + power = institution_power_generated(outputDb, institutionId, truncate=False) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for i in range(simulationBegin + t0, simulationBegin + t0 + period): + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + for j in range(simulationBegin + 1, simulationEnd): + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = rtn['Ratio'] * actualization + return rtn + def institution_period_costs2(outputDb, institutionId, t0=0, period=20, capital=True): - """Just for tests : another method for period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() - simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] - costs = institution_annual_costs(outputDb, institutionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = institution_power_generated(outputDb, institutionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - return rtn - + """Just for tests : another method for period costs + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() + simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] + simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] + costs = institution_annual_costs(outputDb, institutionId, capital, truncate=False) + costs = costs.sum(axis=1) + power = institution_power_generated(outputDb, institutionId, truncate=False) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for j in range(simulationBegin, simulationEnd + 1): + for i in range(j + t0, j + t0 + period): + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + return rtn + def institution_power_generated(outputDb, institutionId, truncate=True): - """Input : sqlite output database and institution agent id - Output : Sum of electricity generated in MWh every year in the institution reactor fleet - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId==institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and xsimulationBegin and xsimulationBegin and xsimulationBegin and xsimulationBegin and x= beginYear)] - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum() - return costs - + """Input : sqlite output database and region's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. + Output : total reactor costs per year over its lifetime at the region level. + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + dfEntry = evaler.eval('AgentEntry').reset_index() + tmp = dfEntry[dfEntry.ParentId==regionId] + dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x= beginYear)] + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum() + return costs + def region_annual_costs_present_value(outputDb, regionId, capital=True, truncate=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION - """ - costs = region_annual_costs(outputDb, regionId, capital) - actualization = actualization_vector(len(costs)) - actualization.index = costs.index - return costs.apply(lambda x : x * actualization) - + """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """ + costs = region_annual_costs(outputDb, regionId, capital) + actualization = actualization_vector(len(costs)) + actualization.index = costs.index + return costs.apply(lambda x : x * actualization) + def region_benefit(outputDb, regionId): - """Input : sqlite output database and region agent id - Output : cumulative sum of actualized income and expense (= - expenditures + income) - """ - costs = - region_annual_costs(outputDb, regionId).sum(axis=1) - power_gen = region_power_generated(outputDb, regionId) * region_average_lcoe(outputDb, regionId)['Average LCOE'] - rtn = pd.concat([costs, power_gen], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn - + """Input : sqlite output database and region agent id + Output : cumulative sum of actualized income and expense (= - expenditures + income) + """ + costs = - region_annual_costs(outputDb, regionId).sum(axis=1) + power_gen = region_power_generated(outputDb, regionId) * region_average_lcoe(outputDb, regionId)['Average LCOE'] + rtn = pd.concat([costs, power_gen], axis=1).fillna(0) + rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() + return rtn + def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): - """Input : sqlite output database, region id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = region_annual_costs(outputDb, regionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = region_power_generated(outputDb, regionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd + 1): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = rtn['Ratio'] * actualization - return rtn - + """Input : sqlite output database, region id, time window (t0, period) + Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + costs = region_annual_costs(outputDb, regionId, capital, truncate=False) + costs = costs.sum(axis=1) + power = region_power_generated(outputDb, regionId, truncate=False) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for i in range(simulationBegin + t0, simulationBegin + t0 + period): + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + for j in range(simulationBegin + 1, simulationEnd + 1): + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = rtn['Ratio'] * actualization + return rtn + def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): - """Just for tests : another method to calculate period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = region_annual_costs(outputDb, regionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = region_power_generated(outputDb, regionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - return rtn - + """Just for tests : another method to calculate period costs + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + costs = region_annual_costs(outputDb, regionId, capital, truncate=False) + costs = costs.sum(axis=1) + power = region_power_generated(outputDb, regionId, truncate=False) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for j in range(simulationBegin, simulationEnd + 1): + for i in range(j + t0, j + t0 + period): + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + return rtn + def region_power_generated(outputDb, regionId, truncate=True): - """Input : sqlite output database and region agent id - Output : Sum of electricity generated in MWh every years in the region reactor fleet - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - tmp = dfEntry[dfEntry.ParentId==regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and xsimulationBegin and xsimulationBegin and xsimulationBegin and xsimulationBegin and x= beginYear)] - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum() - return costs - + """Input : sqlite output database. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. + Output : total reactor costs per year over its lifetime at the simulation level. + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + dfEntry = evaler.eval('AgentEntry').reset_index() + dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x= beginYear)] + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum() + return costs + def simulation_annual_costs_present_value(outputDb, capital=True, truncate=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION - """ - df = simulation_annual_costs(outputDb, capital, truncate) - for year in df.index: - df.loc[year, :] = df.loc[year, :] / (1 + default_discount_rate) ** (year - df.index[0]) - return df - + """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """ + df = simulation_annual_costs(outputDb, capital, truncate) + for year in df.index: + df.loc[year, :] = df.loc[year, :] / (1 + default_discount_rate) ** (year - df.index[0]) + return df + def simulation_benefit(outputDb): - """Input : sqlite output database - Output : cumulative sum of total income and total expense (= - expenditures + income) when all reactors of the simulation are taken into account - """ - costs = - simulation_annual_costs(outputDb).sum(axis=1) - power_gen = simulation_power_generated(outputDb) * simulation_average_lcoe(outputDb)['Average LCOE'] - rtn = pd.concat([costs, power_gen], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn - + """Input : sqlite output database + Output : cumulative sum of total income and total expense (= - expenditures + income) when all reactors of the simulation are taken into account + """ + costs = - simulation_annual_costs(outputDb).sum(axis=1) + power_gen = simulation_power_generated(outputDb) * simulation_average_lcoe(outputDb)['Average LCOE'] + rtn = pd.concat([costs, power_gen], axis=1).fillna(0) + rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() + actualization = actualization_vector(len(rtn)) + actualization.index = rtn.index + rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() + return rtn + def simulation_period_costs(outputDb, t0=0, period=20, capital=True): - """Input : sqlite output database, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of total expense in [t+t0, t+t0+period] divided by total actualized power generated in [t+t0, t+t0+period] when all reactors of the simulation are taken into account - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = simulation_annual_costs(outputDb, capital, truncate=False).sum(axis=1) - power = simulation_power_generated(outputDb, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - return rtn - + """Input : sqlite output database, time window (t0, period) + Output : cost at each time step t corresponding to actualized sum of total expense in [t+t0, t+t0+period] divided by total actualized power generated in [t+t0, t+t0+period] when all reactors of the simulation are taken into account + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + costs = simulation_annual_costs(outputDb, capital, truncate=False).sum(axis=1) + power = simulation_power_generated(outputDb, truncate=False) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for i in range(simulationBegin + t0, simulationBegin + t0 + period): + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + for j in range(simulationBegin + 1, simulationEnd): + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + return rtn + def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): - """Just for tests : another method to calculate the period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = simulation_annual_costs(outputDb, capital, truncate=False).sum(axis=1) - power = simulation_power_generated(outputDb, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) - return rtn - + """Just for tests : another method to calculate the period costs + """ + db = dbopen(outputDb) + evaler = Evaluator(db, write=False) + dfInfo = evaler.eval('Info').reset_index() + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + dfEcoInfo = evaler.eval('EconomicInfo') + simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] + simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] + costs = simulation_annual_costs(outputDb, capital, truncate=False).sum(axis=1) + power = simulation_power_generated(outputDb, truncate=False) + df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df['Power'] = power + df['Costs'] = costs + df = df.fillna(0) + simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear + simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear + rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) + rtn['Power'] = pd.Series() + rtn['Payment'] = pd.Series() + rtn = rtn.fillna(0) + for j in range(simulationBegin, simulationEnd + 1): + for i in range(j + t0, j + t0 + period): + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) + rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + return rtn + def simulation_power_generated(outputDb, truncate=True): - """Input : sqlite output database - Output : Electricity generated in MWh every years by all the reactors of the simulation - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and xsimulationBegin and xsimulationBegin and xsimulationBegin and x b=""" - b = 0.002888279324826512 - return foak * n ** (- b) - + """Input : price of First Of A Kind reactor + Output : price of n-th Of A Kind reactor + http://www.power-eng.com/content/dam/pe/online-articles/documents/2011/july/EPRI.pdf + https://www.netl.doe.gov/File%20Library/research/energy%20analysis/publications/QGESS_FOAKtoNOAK_Final.pdf + http://www.rff.org/events/documents/rffexperiencecurvetalk.pdf LR~20% => b=""" + b = 0.002888279324826512 + return foak * n ** (- b) + def substitution_power_purchase(annualCosts, power, substitutePrice, yearBegin, yearEnd): - """Input : annual costs (Construction costs + fuel costs + O&M + decommissioning), substitute power needed (MWh), price of substitute power ($/MWh), interval of time when the substitute power is needed ([yearBegin, yearEnd[) - Output : annual costs with substitution power - """ - if 'Substitute' in annualCosts.columns: - annualCosts.loc[yearBegin:yearEnd, 'Substitute'] += substitutePrice * power - else: - annualCosts['Substitute'] = pd.Series() - annualCosts = annualCosts.fillna(0) - annualCosts.loc[yearBegin:yearEnd, 'Substitute'] += substitutePrice * power - + """Input : annual costs (Construction costs + fuel costs + O&M + decommissioning), substitute power needed (MWh), price of substitute power ($/MWh), interval of time when the substitute power is needed ([yearBegin, yearEnd[) + Output : annual costs with substitution power + """ + if 'Substitute' in annualCosts.columns: + annualCosts.loc[yearBegin:yearEnd, 'Substitute'] += substitutePrice * power + else: + annualCosts['Substitute'] = pd.Series() + annualCosts = annualCosts.fillna(0) + annualCosts.loc[yearBegin:yearEnd, 'Substitute'] += substitutePrice * power + def isreactor(dfPower, id): - """Input : reactor agent id and pandas DataFrame with power generated. Agent generates power if and only if it is a reactor - Output : boolean (True if agent id corresponds to a reactor, False if not) - """ - return not dfPower[dfPower.AgentId==id].empty + """Input : reactor agent id and pandas DataFrame with power generated. Agent generates power if and only if it is a reactor + Output : boolean (True if agent id corresponds to a reactor, False if not) + """ + return not dfPower[dfPower.AgentId==id].empty ############## # Separation # ############## def isseparation(dfEntry, id): - """Input : Agents entry table and agent id - Output : boolean (True if facility is a separation plant, False if not). - """ - return 'SEP' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() + """Input : Agents entry table and agent id + Output : boolean (True if facility is a separation plant, False if not). + """ + return 'SEP' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() ####################### @@ -135,10 +135,10 @@ def isseparation(dfEntry, id): ####################### def actualization_vector(size, discountRate): - """Output : pandas Series with actualization factors - """ - rtn = pd.Series(1 / (1 + discountRate), index=list(range(size))).cumprod() - return rtn * (1 + discountRate) + """Output : pandas Series with actualization factors + """ + rtn = pd.Series(1 / (1 + discountRate), index=list(range(size))).cumprod() + return rtn * (1 + discountRate) def actualize(price, delta_t, discount_rate): """Given a price at date t + delta_t, give the actualized price at t. @@ -146,6 +146,6 @@ def actualize(price, delta_t, discount_rate): return price / (1 + discount_rate) ** delta_t def inflation(price, date): - """Give the 2015 $ value of a price given in 'date' $ - """ - return price * f_inflation.loc[date, 0] \ No newline at end of file + """Give the 2015 $ value of a price given in 'date' $ + """ + return price * f_inflation.loc[date, 0] diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index e9fa4688..d51a08cc 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -48,22 +48,14 @@ def test_capital_cost(): ) ecoInfo = pd.DataFrame(np.array([ ('Reactor1', 13, 10, 5, 10, 0, 1, 0.1) - ], dtype=ensure_dt_bytes([('Agent_Prototype', 'O'), ('Agent_AgentId', - ' Date: Tue, 28 Apr 2020 16:12:42 -0500 Subject: [PATCH 26/64] fuel_cost --- cymetric/eco_metrics.py | 79 +++++++++++++++++---------------------- tests/test_eco_metrics.py | 36 +++++++----------- 2 files changed, 48 insertions(+), 67 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index fd30b944..c19ef4b8 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -16,7 +16,7 @@ try: from cymetric.metrics import metric - from cymetric.tools import dbopen + from cymetric.tools import dbopen, merge from cymetric.evaluator import Evaluator from cymetric.eco_tools import actualization_vector, isreactor, capital_shape from cymetric.evaluator import register_metric @@ -25,7 +25,7 @@ from .metrics import metric from .evaluator import register_metric from .eco_tools import capital_shape, isreactor, actualization_vector, isreactor - from .tools import dbopen + from .tools import dbopen, merge from .evaluator import Evaluator xml_inputs = 'parameters.xml' # This xml file has to be built in the same direction as the sqlite output database. It contains the economic data needed to calculate the EconomicInfo metric @@ -46,6 +46,7 @@ def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): """The CapitalCost metric gives the cash flows at each time step corresponding to the reactors construction costs. """ + simDuration = dfInfo['Duration'].iloc[0] dfEntry = pd.DataFrame([dfEntry.EnterTime, dfEntry.AgentId]).transpose() #dfEntry = dfEntry.set_index(['AgentId']) @@ -88,54 +89,42 @@ def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): del _ccdeps, _ccschema -_fcdeps = [('Resources', ('SimId', 'ResourceId'), 'Quantity'), ('Transactions', - ('SimId', 'TransactionId', 'ReceiverId', 'ResourceId', 'Commodity'), - 'Time'), ('EconomicInfo', (('Agent', 'Prototype'), ('Agent', 'AgentId'), ('Fuel', 'Commodity'), ('Fuel', 'SupplyCost'), ('Fuel', 'WasteFee'), ('Fuel', 'Deviation')), ('Finance','DiscountRate'))] +_fcdeps = ['Resources', 'Transactions', 'EconomicInfo'] -_fcschema = [('SimId', ts.UUID), ('TransactionId', ts.INT), ('AgentId', - ts.INT), ('Commodity', ts.STRING), ('Payment', ts.DOUBLE), ('Time', - ts.INT)] +_fcschema = [ + ('SimId', ts.UUID), + ('TransactionId', ts.INT), + ('AgentId', ts.INT), + ('Commodity', ts.STRING), + ('Payment', ts.DOUBLE), + ('Time', ts.INT)] @metric(name='FuelCost', depends=_fcdeps, schema=_fcschema) -def fuel_cost(series): +def fuel_cost(dfResources, dfTransactions, dfEcoInfo): """The FuelCost metric gives the cash flows at each time step corresponding to the reactors fuel costs. It also contains the waste fee. """ - dfResources = series[0].reset_index().set_index(['ResourceId']) - dfTransactions = series[1].reset_index().set_index(['ResourceId']) - dfEcoInfo = series[2].reset_index() - tuples = (('Agent', 'Prototype'), ('Agent', 'AgentId'), ('Fuel', 'Commodity'), ('Fuel', 'SupplyCost'), ('Fuel', 'WasteFee'), ('Fuel', 'Deviation'), ('Finance','DiscountRate')) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) - dfEcoInfo.columns = index - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - dfTransactions['Quantity'] = dfResources.loc[:, 'Quantity'] - dfTransactions['Payment'] = pd.Series() - dfTransactions.loc[:, 'Payment'] = dfTransactions.loc[:, 'Payment'].fillna(0) - dfTransactions['Tmp'] = pd.Series() - for agentId in dfEcoInfo.index: - tmpTrans = dfTransactions[dfTransactions.ReceiverId==agentId] - if isinstance(dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')], str): - commod = dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')] - deviation = dfEcoInfo.loc[agentId, ('Fuel', 'Deviation')] - tmpTrans2 = tmpTrans[tmpTrans.Commodity==commod] - deviation = deviation * np.random.randn(1) - price = deviation + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'SupplyCost')] + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'WasteFee')] - dfTransactions.loc[:, 'Tmp'] = tmpTrans2.loc[:, 'Quantity'] * price - elif isinstance(dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')], pd.Series): - for commod in dfEcoInfo.loc[agentId, ('Fuel', 'Commodity')]: - deviation = dfEcoInfo.loc[id, ('Fuel', 'Deviation')] - deviation = deviation * np.random.randn(1) - price = deviation + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'SupplyCost')] + dfEcoInfo[dfEcoInfo[('Fuel', 'Commodity')]==commod].loc[agentId, ('Fuel', 'WasteFee')] - tmpTrans2 = tmpTrans[tmpTrans.Commodity==commod] - dfTransactions.loc[:, 'Tmp'] = tmpTrans2.loc[:, 'Quantity'] * price - dfTransactions.loc[:, 'Payment'] += dfTransactions.loc[:, 'Tmp'].fillna(0) - del dfTransactions['Quantity'] - del dfTransactions['Tmp'] - rtn = dfTransactions.reset_index() - subset = rtn.columns.tolist() - subset = subset[1:5]+subset[6:]+subset[5:6] - rtn = rtn[subset] - rtn.columns = ['SimId', 'TransactionId', 'AgentId', 'Commodity', 'Payment', 'Time'] - return rtn + + # Unsure if it is about Sender or Receiver implementation here and test are not in agreement, taking receiver (using implementation as ref) + rtn = dfTransactions.rename(columns={'ReceiverId': 'AgentId'}) + + # add quantity to Transaction + base_col = ['SimId', 'ResourceId'] + added_col = base_col + ['Quantity'] + rtn = merge(rtn, base_col, dfResources, added_col) + + # Merge Eco with Transaction per ReceiverId and commodity + base_col = ['AgentId', 'Commodity'] + # , 'Finance_DiscountRate'] + added_col = base_col + ['Fuel_SupplyCost', + 'Fuel_WasteFee', 'Fuel_Deviation'] + rtn = merge(rtn, base_col, dfEcoInfo, added_col) + + for index, row in rtn.iterrows(): + rtn.at[index, 'Fuel_Deviation'] *= np.random.randn(1) + rtn['Payment'] = rtn['Quantity'] * \ + (rtn['Fuel_Deviation'] + rtn['Fuel_SupplyCost'] + rtn['Fuel_WasteFee']) + return trn[['SimId', 'TransactionId', 'AgentId', 'Commodity', 'Payment', 'Time']] + del _fcdeps, _fcschema diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index d51a08cc..e5a47950 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -60,15 +60,15 @@ def test_capital_cost(): def test_fuel_cost(): exp = pd.DataFrame(np.array([ - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 0, 13, 'uox', 1, 1), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 1, 13, 'uox', 1, 2), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 2, 13, 'uox', 1, 3), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 3, 13, 'uox', 1, 4), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 4, 13, 'uox', 1, 5), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 5, 13, 'uox', 1, 6), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 6, 13, 'uox', 1, 7), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 7, 13, 'uox', 1, 8), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 8, 13, 'uox', 1, 9) + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 0, 12, 'uox', 1, 1), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 1, 12, 'uox', 1, 2), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 2, 12, 'uox', 1, 3), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 3, 12, 'uox', 1, 4), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 4, 12, 'uox', 1, 5), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 5, 12, 'uox', 1, 6), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 6, 12, 'uox', 1, 7), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 7, 12, 'uox', 1, 8), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 8, 12, 'uox', 1, 9) ], dtype=ensure_dt_bytes([ ('SimId','O'), ('TransactionId', ' Date: Wed, 29 Apr 2020 10:18:40 -0500 Subject: [PATCH 27/64] working decomissionning cost --- cymetric/eco_metrics.py | 75 ++++++++++++++++++++------------------- tests/test_eco_metrics.py | 35 +++++++++--------- 2 files changed, 58 insertions(+), 52 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index c19ef4b8..0c176555 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -129,50 +129,53 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): del _fcdeps, _fcschema -_dcdeps = [ ('TimeSeriesPower', ('SimId', 'AgentId'), 'Value'), - ('AgentEntry', ('EnterTime', 'Lifetime', 'AgentId'), 'Spec'), - ('Info', ('InitialYear', 'InitialMonth'), 'Duration'), ('EconomicInfo', (('Agent', 'AgentId'), ('Decommissioning', 'Duration')), ('Decommissioning', 'OvernightCost'))] +_dcdeps = ['TimeSeriesPower', 'AgentEntry', 'Info', 'EconomicInfo'] + +_dcschema = [ + ('SimId', ts.UUID), + ('AgentId', ts.INT), + ('Payment', ts.DOUBLE), + ('Time', ts.INT)] -_dcschema = [('SimId', ts.UUID), ('AgentId', ts.INT), ('Payment', - ts.DOUBLE), ('Time', ts.INT)] @metric(name='DecommissioningCost', depends=_dcdeps, schema=_dcschema) -def decommissioning_cost(series): +def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): """The Decommissioning cost metric gives the cash flows at each time step corresponding to the reactors decommissioning. """ - if series[0].empty: - return pd.DataFrame() - dfPower = series[0].reset_index() - dfPower = dfPower[dfPower['Value'].apply(lambda x: x > 0)] - dfEntry = series[1].reset_index() - dfInfo = series[2].reset_index() - dfEcoInfo = series[3].reset_index() - tuples = (('Agent', 'AgentId'), ('Decommissioning', 'Duration'), ('Decommissioning', 'OvernightCost')) - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) - dfEcoInfo.columns = index - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - simDuration = dfInfo['Duration'].iloc[0] + + out = ['SimId', 'AgentId', 'Payment', 'Time'] + power = ['SimId', 'AgentId', 'Value'] + entry = ['EnterTime', 'Lifetime', 'AgentId', 'Spec'] + info = ['SimId', 'InitialYear', 'InitialMonth', 'Duration'] + eco = ['AgentId', 'Decommissioning_Duration', + 'Decommissioning_OvernightCost'] + + base_col = ['AgentId'] + added_col = base_col + ['Value'] + dfEcoInfo = pd.merge(dfPower[added_col], dfEcoInfo, on=base_col) + dfEcoInfo.rename(columns={'Value': 'PowerCapacity'}, inplace=True) dfEntry = dfEntry[dfEntry['Lifetime'].apply(lambda x: x > 0)] - dfEntry = dfEntry[(dfEntry['EnterTime'] + dfEntry['Lifetime']).apply(lambda x: x < simDuration)] # only reactors that will be decommissioned - reactorsId = dfEntry[dfEntry['Spec'].apply(lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() + reactorsId = dfEntry[dfEntry['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() + print(reactorsId) rtn = pd.DataFrame() for id in reactorsId: - tmp = dfEcoInfo.loc[id].copy() - if isinstance(tmp,pd.DataFrame): - tmp = tmp.iloc[0] - duration = int(tmp.loc[('Decommissioning', 'Duration')]) - overnightCost = tmp.loc[('Decommissioning', 'OvernightCost')] - cashFlowShape = capital_shape(duration - duration // 2, duration // 2) - powerCapacity = dfPower[dfPower.AgentId==id]['Value'].iloc[0] - cashFlow = cashFlowShape * powerCapacity * overnightCost - entryTime = dfEntry[dfEntry.AgentId==id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId==id]['Lifetime'].iloc[0] - rtn = pd.concat([rtn,pd.DataFrame({'AgentId': id, 'Time': list(range(lifetime + entryTime, lifetime + entryTime + duration + 1)), 'Payment': cashFlow})], ignore_index=True) - rtn['SimId'] = dfPower['SimId'].iloc[0] - subset = rtn.columns.tolist() - subset = subset[-1:]+subset[:-1] - rtn = rtn[subset] - return rtn[rtn['Time'].apply(lambda x: x >= 0 and x < simDuration)] + tmp = dfEcoInfo[dfEntry['AgentId'] == id] + if(len(tmp) == 1): + duration = int(tmp.at[0, 'Decommissioning_Duration']) + print(duration) + overnightCost = tmp.at[0, 'Decommissioning_OvernightCost'] + cashFlowShape = capital_shape( + duration - duration // 2, duration // 2) + powerCapacity = tmp.at[0, 'PowerCapacity'] + cashFlow = cashFlowShape * powerCapacity * overnightCost + entryTime = dfEntry[dfEntry.AgentId == id]['EnterTime'][0] + lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'][0] + rtn = pd.concat([rtn, pd.DataFrame({'AgentId': id, 'Time': list(range( + lifetime + entryTime, lifetime + entryTime + duration + 1)), 'Payment': cashFlow})], ignore_index=True) + rtn['SimId'] = dfPower['SimId'][0] + return rtn[['SimId', 'AgentId', 'Payment', 'Time']] + del _dcdeps, _dcschema diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index e5a47950..ab47c688 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -140,39 +140,42 @@ def test_decommissioning_cost(): (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 0.2, 15), (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 0.0, 16) ], dtype=ensure_dt_bytes([ - ('SimId','O'), ('AgentId', ' Date: Fri, 1 May 2020 09:40:44 -0500 Subject: [PATCH 28/64] formating --- cymetric/eco_metrics.py | 112 ++++++++++++-------- tests/test_eco_metrics.py | 209 +++++++++++++++++++++----------------- 2 files changed, 186 insertions(+), 135 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 0c176555..94055c3a 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -1,4 +1,4 @@ -##### economic metrics for nuclear power plants ##### +# economic metrics for nuclear power plants ##### from __future__ import print_function, unicode_literals @@ -18,19 +18,26 @@ from cymetric.metrics import metric from cymetric.tools import dbopen, merge from cymetric.evaluator import Evaluator - from cymetric.eco_tools import actualization_vector, isreactor, capital_shape + from cymetric.eco_tools import actualization_vector, isreactor, \ + capital_shape from cymetric.evaluator import register_metric except ImportError: # some wacky CI paths prevent absolute importing, try relative from .metrics import metric from .evaluator import register_metric - from .eco_tools import capital_shape, isreactor, actualization_vector, isreactor + from .eco_tools import capital_shape, isreactor, actualization_vector, \ + isreactor from .tools import dbopen, merge from .evaluator import Evaluator -xml_inputs = 'parameters.xml' # This xml file has to be built in the same direction as the sqlite output database. It contains the economic data needed to calculate the EconomicInfo metric -## The actual metrics ## +# This xml file has to be built in the same direction as the sqlite output +# database. It contains the economic data needed to calculate the EconomicInfo +# metric +xml_inputs = 'parameters.xml' + + +# The actual metrics ## _ccdeps = ['TimeSeriesPower', 'AgentEntry', 'Info', 'EconomicInfo'] @@ -44,12 +51,12 @@ @metric(name='CapitalCost', depends=_ccdeps, schema=_ccschema) def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): - """The CapitalCost metric gives the cash flows at each time step corresponding to the reactors construction costs. + """The CapitalCost metric gives the cash flows at each time step + corresponding to the reactors construction costs. """ simDuration = dfInfo['Duration'].iloc[0] dfEntry = pd.DataFrame([dfEntry.EnterTime, dfEntry.AgentId]).transpose() - #dfEntry = dfEntry.set_index(['AgentId']) rtn = pd.DataFrame() for index, eco_row in dfEcoInfo.iterrows(): id = eco_row['AgentId'] @@ -70,12 +77,18 @@ def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): discountRate = eco_row['Finance_DiscountRate'] cashFlow = np.around( cashFlowShape * overnightCost * powerCapacity, 4) - cashFlow *= ((1 + discountRate) ** math.ceil((beforePeak + afterPeak) / 12) - - 1) / (discountRate * math.ceil((beforePeak + afterPeak) / 12)) + cashFlow *= ((1 + discountRate) + ** math.ceil((beforePeak + afterPeak) / 12) - + 1) / (discountRate + * math.ceil((beforePeak + afterPeak) / 12)) tmp = pd.DataFrame(data={'AgentId': id, - 'Time': pd.Series(list(range(beforePeak + afterPeak + 1))) - + entry_time - constructionDuration, + 'Time': pd.Series( + list(range(beforePeak + + afterPeak + + 1))) + + entry_time + - constructionDuration, 'Payment': cashFlow}, columns=['AgentId', 'Time', 'Payment']) rtn = pd.concat([rtn, tmp], ignore_index=False) @@ -99,12 +112,15 @@ def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): ('Payment', ts.DOUBLE), ('Time', ts.INT)] + @metric(name='FuelCost', depends=_fcdeps, schema=_fcschema) def fuel_cost(dfResources, dfTransactions, dfEcoInfo): - """The FuelCost metric gives the cash flows at each time step corresponding to the reactors fuel costs. It also contains the waste fee. + """The FuelCost metric gives the cash flows at each time step corresponding + to the reactors fuel costs. It also contains the waste fee. """ - # Unsure if it is about Sender or Receiver implementation here and test are not in agreement, taking receiver (using implementation as ref) +# Unsure if it is about Sender or Receiver implementation here and test are not +# in agreement, taking receiver (using implementation as ref) rtn = dfTransactions.rename(columns={'ReceiverId': 'AgentId'}) # add quantity to Transaction @@ -123,7 +139,13 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): rtn.at[index, 'Fuel_Deviation'] *= np.random.randn(1) rtn['Payment'] = rtn['Quantity'] * \ (rtn['Fuel_Deviation'] + rtn['Fuel_SupplyCost'] + rtn['Fuel_WasteFee']) - return trn[['SimId', 'TransactionId', 'AgentId', 'Commodity', 'Payment', 'Time']] + rtn = rtn[['SimId', + 'TransactionId', + 'AgentId', + 'Commodity', + 'Payment', + 'Time']] + return rtn del _fcdeps, _fcschema @@ -140,16 +162,10 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): @metric(name='DecommissioningCost', depends=_dcdeps, schema=_dcschema) def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): - """The Decommissioning cost metric gives the cash flows at each time step corresponding to the reactors decommissioning. + """The Decommissioning cost metric gives the cash flows at each time step + corresponding to the reactors decommissioning. """ - out = ['SimId', 'AgentId', 'Payment', 'Time'] - power = ['SimId', 'AgentId', 'Value'] - entry = ['EnterTime', 'Lifetime', 'AgentId', 'Spec'] - info = ['SimId', 'InitialYear', 'InitialMonth', 'Duration'] - eco = ['AgentId', 'Decommissioning_Duration', - 'Decommissioning_OvernightCost'] - base_col = ['AgentId'] added_col = base_col + ['Value'] dfEcoInfo = pd.merge(dfPower[added_col], dfEcoInfo, on=base_col) @@ -171,8 +187,12 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): cashFlow = cashFlowShape * powerCapacity * overnightCost entryTime = dfEntry[dfEntry.AgentId == id]['EnterTime'][0] lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'][0] - rtn = pd.concat([rtn, pd.DataFrame({'AgentId': id, 'Time': list(range( - lifetime + entryTime, lifetime + entryTime + duration + 1)), 'Payment': cashFlow})], ignore_index=True) + time_pdf = pd.DataFrame({'AgentId': id, + 'Time': list(range(lifetime + entryTime, + lifetime + entryTime + + duration + 1)), + 'Payment': cashFlow}) + rtn = pd.concat([rtn, time_pdf], ignore_index=True) rtn['SimId'] = dfPower['SimId'][0] return rtn[['SimId', 'AgentId', 'Payment', 'Time']] @@ -182,20 +202,36 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): _omdeps = ['TimeSeriesPower', 'EconomicInfo'] -_omschema = [('SimId', ts.UUID), ('AgentId', ts.INT), ('Time', ts.INT), - ('Payment', ts.DOUBLE)] +_omschema = [('SimId', ts.UUID), + ('AgentId', ts.INT), + ('Time', ts.INT), + ('Payment', ts.DOUBLE)] + @metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) def operation_maintenance(s1, s2): - """The OperationMaintenance metric gives the cash flows at each time step corresponding to the reactor operations and maintenance costs. + """The OperationMaintenance metric gives the cash flows at each time step + corresponding to the reactor operations and maintenance costs. """ - rtn = s1 - dfEcoInfo = s2 - index = ['AgentId', 'FixedCost', - 'VariableCost', - 'Deviation'] - #index = pd.MultiIndex.from_tuples(tuples) - #dfEcoInfo.columns = index + exp = ['SimId', 'AgentId', 'Time', 'Payment'] + power = ['SimId', 'AgentId', 'Time', 'Value'] + ecoInfo = ['AgentId', 'FixedCost', 'VariableCost', 'Operation_Deviation'] + rtn = dfEcoInfo + for index, row in rtn.iterrows(): + rtn.at[index, 'Operation_Deviation'] *= np.random.randn(1) + rtn['FixedCost'] *= rtn['Operation_Deviation'] + rtn['VariableCost'] *= rtn['Operation_Deviation'] + + base_col = ['AgentId'] + added_col = base_col + ['Value'] + dfEcoInfo = pd.merge(dfPower[added_col], dfEcoInfo, on=base_col) + dfEcoInfo['Value'] *= 8760 / 12 + rtn['Payment'] = rtn['Value'] + rtn['Payment'] = rtn['Quantity'] * \ + (rtn['Fuel_Deviation'] + rtn['Fuel_SupplyCost'] + rtn['Fuel_WasteFee']) + + + dfEcoInfo = dfEcoInfo.set_index('AgentId') print(rtn) print(dfEcoInfo) @@ -206,14 +242,6 @@ def operation_maintenance(s1, s2): if isreactor(rtn, id): powerGenerated = rtn[rtn.AgentId==id].loc[:,'Value'] powerCapacity = max(powerGenerated) - powerGenerated *= 8760 / 12 - tmp = dfEcoInfo.loc[id].copy() - if isinstance(tmp,pd.DataFrame): - tmp = tmp.iloc[0] - deviation = tmp.loc['Deviation'] - deviation *= np.random.randn(1) - fixedOM = tmp.loc['FixedCost'] + deviation - variableOM = tmp.loc['VariableCost'] + deviation rtn['tmp'] = powerGenerated * variableOM + powerCapacity * fixedOM rtn.loc[:, 'Payment'] += rtn.loc[:, 'tmp'].fillna(0) rtn = rtn.reset_index() diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index ab47c688..fb605e53 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -26,36 +26,40 @@ def test_capital_cost(): (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 4, 0.055965), (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 5, 0.028035), (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 6, 0.0) - ], dtype=ensure_dt_bytes([ - ('SimId','O'), ('AgentId', ' Date: Fri, 1 May 2020 12:54:58 -0500 Subject: [PATCH 29/64] operation maintenance --- cymetric/eco_metrics.py | 132 ++++++++++++++++++++------------------ tests/test_eco_metrics.py | 24 +++---- 2 files changed, 82 insertions(+), 74 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 94055c3a..824c4729 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -209,7 +209,7 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): @metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) -def operation_maintenance(s1, s2): +def operation_maintenance(dfPower, dfEcoInfo): """The OperationMaintenance metric gives the cash flows at each time step corresponding to the reactor operations and maintenance costs. """ @@ -219,69 +219,78 @@ def operation_maintenance(s1, s2): rtn = dfEcoInfo for index, row in rtn.iterrows(): rtn.at[index, 'Operation_Deviation'] *= np.random.randn(1) - rtn['FixedCost'] *= rtn['Operation_Deviation'] - rtn['VariableCost'] *= rtn['Operation_Deviation'] + rtn['FixedCost'] += rtn['Operation_Deviation'] + rtn['VariableCost'] += rtn['Operation_Deviation'] base_col = ['AgentId'] - added_col = base_col + ['Value'] - dfEcoInfo = pd.merge(dfPower[added_col], dfEcoInfo, on=base_col) - dfEcoInfo['Value'] *= 8760 / 12 - rtn['Payment'] = rtn['Value'] - rtn['Payment'] = rtn['Quantity'] * \ - (rtn['Fuel_Deviation'] + rtn['Fuel_SupplyCost'] + rtn['Fuel_WasteFee']) - + added_col = base_col + ['SimId', 'Time', 'Value'] + rtn = pd.merge(dfPower[added_col], rtn, on=base_col) + rtn['Value'] *= 8760 / 12 + rtn['Payment'] = (rtn['Value'] * rtn['VariableCost'] + + max(rtn['Value'])*rtn['FixedCost']) + return rtn[['SimId', 'AgentId', 'Time', 'Payment']] - dfEcoInfo = dfEcoInfo.set_index('AgentId') - print(rtn) - print(dfEcoInfo) - dfEcoInfo = dfEcoInfo - rtn['Payment'] = 0 - rtn['tmp'] = 0 - for id in dfEcoInfo.index: - if isreactor(rtn, id): - powerGenerated = rtn[rtn.AgentId==id].loc[:,'Value'] - powerCapacity = max(powerGenerated) - rtn['tmp'] = powerGenerated * variableOM + powerCapacity * fixedOM - rtn.loc[:, 'Payment'] += rtn.loc[:, 'tmp'].fillna(0) - rtn = rtn.reset_index() - del rtn['Value'], rtn['index'], rtn['tmp'] - return rtn del _omdeps, _omschema -_eideps = [('AgentEntry', ('AgentId', 'Prototype'), 'ParentId')] - -_eischema = [('Agent_Prototype', ts.STRING), ('Agent_AgentId', ts.INT), - ('Agent_ParentId', ts.INT), ('Finance_ReturnOnDebt', ts.DOUBLE), - ('Finance_ReturnOnEquity', ts.DOUBLE), ('Finance_TaxRate', ts.DOUBLE), - ('Finance_DiscountRate', ts.DOUBLE), ('Capital_beforePeak', ts.INT), - ('Capital_afterPeak', ts.INT), ('Capital_constructionDuration', ts.INT), - ('Capital_Deviation', ts.DOUBLE), ('Capital_OvernightCost', ts.DOUBLE), - ('Decommissioning_Duration', ts.INT), - ('Decommissioning_OvernightCost', ts.DOUBLE), - ('OperationMaintenance_FixedCost', ts.DOUBLE), - ('OperationMaintenance_VariableCost', ts.DOUBLE), - ('OperationMaintenance_Deviation', ts.DOUBLE), - ('FuelCommodity', ts.STRING), ('Fuel_SupplyCost', ts.DOUBLE), - ('Fuel_WasteFee', ts.DOUBLE), ('Fuel_Deviation', ts.DOUBLE), - ('Truncation_Begin', ts.INT), ('Truncation_End', ts.INT)] - +_eideps = ['AgentEntry', 'ParentId'] + +_eischema = [('Agent_Prototype', ts.STRING), + ('Agent_AgentId', ts.INT), + ('Agent_ParentId', ts.INT), + ('Finance_ReturnOnDebt', ts.DOUBLE), + ('Finance_ReturnOnEquity', ts.DOUBLE), + ('Finance_TaxRate', ts.DOUBLE), + ('Finance_DiscountRate', ts.DOUBLE), + ('Capital_beforePeak', ts.INT), + ('Capital_afterPeak', ts.INT), + ('Capital_constructionDuration', ts.INT), + ('Capital_Deviation', ts.DOUBLE), + ('Capital_OvernightCost', ts.DOUBLE), + ('Decommissioning_Duration', ts.INT), + ('Decommissioning_OvernightCost', ts.DOUBLE), + ('OperationMaintenance_FixedCost', ts.DOUBLE), + ('OperationMaintenance_VariableCost', ts.DOUBLE), + ('OperationMaintenance_Deviation', ts.DOUBLE), + ('FuelCommodity', ts.STRING), + ('Fuel_SupplyCost', ts.DOUBLE), + ('Fuel_WasteFee', ts.DOUBLE), + ('Fuel_Deviation', ts.DOUBLE), + ('Truncation_Begin', ts.INT), + ('Truncation_End', ts.INT)] + + @metric(name='EconomicInfo', depends=_eideps, schema=_eischema) def economic_info(series): - """The EconomicInfo metric stores all economic data needed to calculate the economic metrics. These economic parameters are originally written in 'parameters.xml'. + """The EconomicInfo metric stores all economic data needed to calculate the + economic metrics. These economic parameters are originally written in + 'parameters.xml'. """ - tuples = ['Agent_Prototype', 'Agent_AgentId', 'Agent_ParentId', - 'Finance_ReturnOnDebt', 'Finance_ReturnOnEquity', 'Finance_TaxRate', - 'Finance_DiscountRate', 'Captial_beforePeak', 'Captial_afterPeak', - 'Captial_constructionDuration', 'Captial_Deviation', - 'Captial_OvernightCost', 'Decommissioning_Duration', - 'Decommissioning_OvernightCost', 'OperationMaintenance_FixedCost', - 'OperationMaintenance_VariableCost', - 'OperationMaintenance_Deviation', 'Fuel_Commodity', - 'Fuel_SupplyCost', 'Fuel_WasteFee', 'Fuel_Deviation', - 'Truncation_Begin', 'Truncation_End'] + tuples = ['Agent_Prototype', + 'Agent_AgentId', + 'Agent_ParentId', + 'Finance_ReturnOnDebt', + 'Finance_ReturnOnEquity', + 'Finance_TaxRate', + 'Finance_DiscountRate', + 'Captial_beforePeak', + 'Captial_afterPeak', + 'Captial_constructionDuration', + 'Captial_Deviation', + 'Captial_OvernightCost', + 'Decommissioning_Duration', + 'Decommissioning_OvernightCost', + 'OperationMaintenance_FixedCost', + 'OperationMaintenance_VariableCost', + 'OperationMaintenance_Deviation', + 'Fuel_Commodity', + 'Fuel_SupplyCost', + 'Fuel_WasteFee', + 'Fuel_Deviation', + 'Truncation_Begin', + 'Truncation_End'] index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) rtn = pd.DataFrame(index=index) dfEntry = series[0].reset_index() @@ -303,24 +312,24 @@ def economic_info(series): rtn.loc[:, 'Finance_ReturnOnEquity'] = float(finance.find('return_on_equity').text) rtn.loc[:, 'Finance_DiscountRate'] = float(finance.find('discount_rate').text) capital = root.find('capital') - if not capital == None: + if capital != None: rtn.loc[:, 'Capital_beforePeak'] = int(capital.find('beforePeak').text) rtn.loc[:, 'Capital_afterPeak'] = int(capital.find('afterPeak').text) rtn.loc[:, 'Capital_constructionDuration'] = int(capital.find('constructionDuration').text) rtn.loc[:, 'Capital_Deviation'] = float(capital.find('deviation').text) rtn.loc[:, 'Capital_OvernightCost'] = float(capital.find('overnight_cost').text) decommissioning = root.find('decommissioning') - if not decommissioning == None: + if decommissioning != None: rtn.loc[:, 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) rtn.loc[:, 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) operation_maintenance = root.find('operation_maintenance') - if not operation_maintenance == None: + if operation_maintenance != None: rtn.loc[:, 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) rtn.loc[:, 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) rtn.loc[:, 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) fuel = root.find('fuel') indexCopy = rtn.index.copy() - if not fuel == None: + if fuel != None: for type in fuel.findall('type'): supply = float(type.find('supply_cost').text) waste = float(type.find('waste_fee').text) @@ -342,7 +351,7 @@ def economic_info(series): for region in root.findall('region'): idRegion = int(region.find('id').text) finance = region.find('finance') - if not finance == None: + if finance != None: returnOnDebt = float(finance.find('return_on_debt').text) returnOnEquity = float(finance.find('return_on_equity').text) taxRate = float(finance.find('tax_rate').text) @@ -636,21 +645,18 @@ def economic_info(series): rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) return rtn - -del _eideps, _eischema +del _eideps, _eischema + """The functions below aim at calculating more complex metrics than the simple cash flows corresponding to the construction, fuel, O&M and decommissioning costs. The metrics can be calculated at an agent, institution, region or simulation level. """ - - ####################################### # Metrics derived from the cash flows # ####################################### - # Reactor level def annual_costs(outputDb, reactorId, capital=True): diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index fb605e53..6a842fac 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -192,15 +192,15 @@ def test_decommissioning_cost(): def test_operation_maintenance(): exp = pd.DataFrame(np.array([ - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 1, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 2, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 3, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 4, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 5, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 6, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 7, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 8, 731), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 9, 731) + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 1, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 2, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 3, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 4, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 5, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 6, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 7, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 8, 1095), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 9, 1095) ], dtype=ensure_dt_bytes([('SimId', 'O'), ('AgentId', ' Date: Mon, 4 May 2020 12:11:50 -0500 Subject: [PATCH 30/64] syntax fixes --- cymetric/eco_tools.py | 130 +++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 40 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 4e49652a..69f44548 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -1,5 +1,8 @@ -"""This file stores several tools that are very useful for the economic analysis (e.g. for eco_metrics.py) as it adds complexity and most importantly realism. First some financial parameters are taken from papers about nuclear power economics. Second, some functions give several modeling options in the metrics calculations. -All prices are 2015 $ +"""This file stores several tools that are very useful for the economic +analysis (e.g. for eco_metrics.py) as it adds complexity and most importantly +realism. First some financial parameters are taken from papers about nuclear +power economics. Second, some functions give several modeling options in the +metrics calculations. All prices are 2015 $ """ import pandas as pd @@ -12,63 +15,79 @@ #################### def isuraniumsource(dfEntry, id): - """Input : Agents entry table and agent id + """ + Input : Agents entry table and agent id Output : boolean (True if facility is a mining facility, False if not). """ - return 'SOURCE' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() + return 'SOURCE' in dfEntry[dfEntry.AgentId == id]['Spec'].iloc[0].upper() + ############## # Conversion # ############## + def isconversionplant(dfEntry, id): - """Input : Agent entry table and agent id + """ + Input : Agent entry table and agent id Output : boolean (True if facility is a conversion plant, False if not). """ - return 'CONV' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() + return 'CONV' in dfEntry[dfEntry.AgentId == id]['Spec'].iloc[0].upper() ############## # Enrichment # ############## + def swu(feedMass, feedAssay, productMass, productAssay, wasteMass, wasteAssay): - """Input : mass and assay of feed, product and waste + """ + Input : mass and assay of feed, product and waste Output : corresponding amount of swu """ - return wasteMass * V(wasteAssay) + productMass * V(productAssay) - feedMass * V(feedAssay) - + rtn_value = wasteMass * V(wasteAssay) + productMass * V(productAssay) \ + - feedMass * V(feedAssay) + + def waste_mass(feedMass, productMass): - """Input : feed and product masses + """ + Input : feed and product masses Output : waste mass """ return feedMass - productMass - + + def waste_assay(feedMass, feedAssay, productMass, productAssay, wasteMass): - """Input : mass of feed, product and waste, assay of feed and product + """ + Input : mass of feed, product and waste, assay of feed and product Output : waste assay """ return (feedMass * feedAssay - productMass * productAssay) / wasteMass + def V(x): """Value function used to calculate the swu """ return (2 * x - 1) * math.log(x / (1 - x)) - + + def isenrichmentplant(dfEntry, id): - """Input : Agents entry table and agent id + """ + Input : Agents entry table and agent id Output : boolean (True if facility is an enrichment plant, False if not). """ - return 'ENRICH' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() + return 'ENRICH' in dfEntry[dfEntry.AgentId == id]['Spec'].iloc[0].upper() ############### # Fabrication # ############### + def isfuelfab(dfEntry, id): - """Input : Agents entry table and agent id - Output : boolean (True if facility is a fuel fabrication plant, False if not). """ - return 'FAB' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() + Input : Agents entry table and agent id + Output : boolean (True if facility is a fuel fabrication plant). + """ + return 'FAB' in dfEntry[dfEntry.AgentId == id]['Spec'].iloc[0].upper() ########### # Reactor # @@ -76,58 +95,87 @@ def isfuelfab(dfEntry, id): def capital_shape(beforePeak=48, afterPeak=48): - """Input : relative position of to the peak.two parameters defining the size of the shape + """ + Input : relative position of to the peak.two parameters defining the size + of the shape Output : curve with integral equals to one in the requested shape. """ if (not isinstance(beforePeak, int)) or (not isinstance(afterPeak, int)): raise Exception("input parameters must be integers") - step1 = pd.Series(list(range(beforePeak))).apply(lambda x: 2/(beforePeak*(beforePeak+afterPeak))*x) - step2 = pd.Series(list(range(beforePeak, beforePeak + afterPeak + 1))).apply(lambda x: -2/(afterPeak*(beforePeak+afterPeak))*(x-(beforePeak+afterPeak))) + step1 = pd.Series(list(range(beforePeak))).apply( + lambda x: 2/(beforePeak*(beforePeak+afterPeak))*x) + step2 = pd.Series( + list(range(beforePeak, beforePeak + afterPeak + 1))).apply( + lambda x: -2 / afterPeak * (beforePeak + afterPeak) + * (x + - beforePeak + + afterPeak)) return pd.concat([step1, step2]).reset_index()[0] - - -def discount_rate(amountOfDebt, amountOfEquity, taxRate, returnOnDebt, returnOnEquity, inflationRate): - """Input : share of debt, share of equity, tax rate, return on debt, return on equity and inflation rate + + +def discount_rate(amountOfDebt, amountOfEquity, taxRate, + returnOnDebt, returnOnEquity, inflationRate): + """ + Input : share of debt, share of equity, tax rate, return on debt, return on + equity and inflation rate Output : corresponding discount rate - D'Haeseleer p.81""" + source: D'Haeseleer p.81 + """ nominalRate = returnOnDebt * amountOfDebt + returnOnEquity * amountOfEquity realRate = (1 + nominalRate) / (1 + inflationRate) - 1 - + + def overnight_cost(foak, n): - """Input : price of First Of A Kind reactor + """ + Input : price of First Of A Kind reactor Output : price of n-th Of A Kind reactor + source : http://www.power-eng.com/content/dam/pe/online-articles/documents/2011/july/EPRI.pdf https://www.netl.doe.gov/File%20Library/research/energy%20analysis/publications/QGESS_FOAKtoNOAK_Final.pdf - http://www.rff.org/events/documents/rffexperiencecurvetalk.pdf LR~20% => b=""" + http://www.rff.org/events/documents/rffexperiencecurvetalk.pdf + LR~20% => b= + """ b = 0.002888279324826512 - return foak * n ** (- b) - -def substitution_power_purchase(annualCosts, power, substitutePrice, yearBegin, yearEnd): - """Input : annual costs (Construction costs + fuel costs + O&M + decommissioning), substitute power needed (MWh), price of substitute power ($/MWh), interval of time when the substitute power is needed ([yearBegin, yearEnd[) + return foak * n ** (-b) + + +def substitution_power_purchase(annualCosts, power, substitutePrice, + yearBegin, yearEnd): + """ + Input : annual costs (Construction costs + fuel costs + O&M + + decommissioning), substitute power needed (MWh), price of substitute power + ($/MWh), interval of time when the substitute power is needed ([yearBegin, + yearEnd[) Output : annual costs with substitution power """ if 'Substitute' in annualCosts.columns: - annualCosts.loc[yearBegin:yearEnd, 'Substitute'] += substitutePrice * power + annualCosts.loc[yearBegin:yearEnd, + 'Substitute'] += substitutePrice * power else: annualCosts['Substitute'] = pd.Series() annualCosts = annualCosts.fillna(0) - annualCosts.loc[yearBegin:yearEnd, 'Substitute'] += substitutePrice * power - + annualCosts.loc[yearBegin:yearEnd, + 'Substitute'] += substitutePrice * power + + def isreactor(dfPower, id): - """Input : reactor agent id and pandas DataFrame with power generated. Agent generates power if and only if it is a reactor + """ + Input : reactor agent id and pandas DataFrame with power generated. Agent + generates power if and only if it is a reactor Output : boolean (True if agent id corresponds to a reactor, False if not) """ - return not dfPower[dfPower.AgentId==id].empty + return not dfPower[dfPower.AgentId == id].empty ############## # Separation # ############## + def isseparation(dfEntry, id): """Input : Agents entry table and agent id Output : boolean (True if facility is a separation plant, False if not). """ - return 'SEP' in dfEntry[dfEntry.AgentId==id]['Spec'].iloc[0].upper() + return 'SEP' in dfEntry[dfEntry.AgentId == id]['Spec'].iloc[0].upper() ####################### @@ -140,11 +188,13 @@ def actualization_vector(size, discountRate): rtn = pd.Series(1 / (1 + discountRate), index=list(range(size))).cumprod() return rtn * (1 + discountRate) + def actualize(price, delta_t, discount_rate): """Given a price at date t + delta_t, give the actualized price at t. """ return price / (1 + discount_rate) ** delta_t - + + def inflation(price, date): """Give the 2015 $ value of a price given in 'date' $ """ From a6d7a5ea4db40273120d26938f268a47513c53ee Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Mon, 4 May 2020 17:28:46 -0500 Subject: [PATCH 31/64] clean and fixed (again) CapitalCost --- cymetric/eco_metrics.py | 113 +++++++++++++++++++------------------- cymetric/eco_tools.py | 17 +++--- tests/test_eco_metrics.py | 38 +++++++++---- 3 files changed, 94 insertions(+), 74 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 824c4729..ef698ede 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -66,29 +66,29 @@ def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): beforePeak = int(eco_row['Capital_beforePeak'] + deviation) afterPeak = int(eco_row['Capital_afterPeak']) + cashFlowShape = capital_shape(beforePeak, afterPeak) - entry_time = dfEntry[dfEntry['AgentId'] == id].EnterTime.values[0] - constructionDuration = int( - eco_row['Capital_constructionDuration'] + deviation) - powerCapacity = max(dfPower[dfPower.AgentId == id]['Value']) + constructionDuration = int(eco_row['Capital_constructionDuration'] + + deviation) + powerCapacity = max(dfPower[dfPower.AgentId == id]['Value']) overnightCost = eco_row['Capital_OvernightCost'] - cashFlowShape = capital_shape(beforePeak, afterPeak) + cashFlow = np.around(cashFlowShape + * overnightCost + * powerCapacity, 4) + discountRate = eco_row['Finance_DiscountRate'] - cashFlow = np.around( - cashFlowShape * overnightCost * powerCapacity, 4) cashFlow *= ((1 + discountRate) ** math.ceil((beforePeak + afterPeak) / 12) - 1) / (discountRate * math.ceil((beforePeak + afterPeak) / 12)) + entry_time = dfEntry[dfEntry['AgentId'] == id].EnterTime.values[0] + TimeSerie = list(range(beforePeak + afterPeak + 1)) + TimeSerie += entry_time - constructionDuration + tmp = pd.DataFrame(data={'AgentId': id, - 'Time': pd.Series( - list(range(beforePeak - + afterPeak - + 1))) - + entry_time - - constructionDuration, + 'Time': TimeSerie, 'Payment': cashFlow}, columns=['AgentId', 'Time', 'Payment']) rtn = pd.concat([rtn, tmp], ignore_index=False) @@ -235,7 +235,7 @@ def operation_maintenance(dfPower, dfEcoInfo): del _omdeps, _omschema -_eideps = ['AgentEntry', 'ParentId'] +_eideps = ['AgentEntry'] _eischema = [('Agent_Prototype', ts.STRING), ('Agent_AgentId', ts.INT), @@ -306,30 +306,30 @@ def economic_info(series): rtn['Truncation_Begin'] = int(truncation.find('simulation_begin').text) rtn['Truncation_End'] = int(truncation.find('simulation_end').text) finance = root.find('finance') - if not finance == None: + if finance is not None: rtn.loc[:, 'Finance_TaxRate'] = float(finance.find('tax_rate').text) rtn.loc[:, 'Finance_ReturnOnDebt'] = float(finance.find('return_on_debt').text) rtn.loc[:, 'Finance_ReturnOnEquity'] = float(finance.find('return_on_equity').text) rtn.loc[:, 'Finance_DiscountRate'] = float(finance.find('discount_rate').text) capital = root.find('capital') - if capital != None: + if capital is not None: rtn.loc[:, 'Capital_beforePeak'] = int(capital.find('beforePeak').text) rtn.loc[:, 'Capital_afterPeak'] = int(capital.find('afterPeak').text) rtn.loc[:, 'Capital_constructionDuration'] = int(capital.find('constructionDuration').text) rtn.loc[:, 'Capital_Deviation'] = float(capital.find('deviation').text) rtn.loc[:, 'Capital_OvernightCost'] = float(capital.find('overnight_cost').text) decommissioning = root.find('decommissioning') - if decommissioning != None: + if decommissioning is not None: rtn.loc[:, 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) rtn.loc[:, 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) operation_maintenance = root.find('operation_maintenance') - if operation_maintenance != None: + if operation_maintenance is not None: rtn.loc[:, 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) rtn.loc[:, 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) rtn.loc[:, 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) fuel = root.find('fuel') indexCopy = rtn.index.copy() - if fuel != None: + if fuel is not None: for type in fuel.findall('type'): supply = float(type.find('supply_cost').text) waste = float(type.find('waste_fee').text) @@ -351,7 +351,7 @@ def economic_info(series): for region in root.findall('region'): idRegion = int(region.find('id').text) finance = region.find('finance') - if finance != None: + if finance is not None: returnOnDebt = float(finance.find('return_on_debt').text) returnOnEquity = float(finance.find('return_on_equity').text) taxRate = float(finance.find('tax_rate').text) @@ -693,7 +693,7 @@ def annual_costs(outputDb, reactorId, capital=True): del costs['Capital'] costs = costs.groupby('Year').sum() return costs - + def annual_costs_present_value(outputDb, reactorId, capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ @@ -701,7 +701,7 @@ def annual_costs_present_value(outputDb, reactorId, capital=True): actualization = actualization_vector(len(costs)) actualization.index = costs.index return costs.apply(lambda x : x * actualization) - + def average_cost(outputDb, reactorId, capital=True): """Input : sqlite output database, reactor's AgentId Output : value (in $/MWh) corresponding to the total costs (sum of annual costs) divided by the total power generated. @@ -711,7 +711,7 @@ def average_cost(outputDb, reactorId, capital=True): dfPower = evaler.eval('TimeSeriesPower').reset_index() powerGenerated = sum(dfPower[dfPower.AgentId==reactorId].loc[:, 'Value']) * 8760 / 12 return annual_costs(outputDb, reactorId, capital).sum().sum() / powerGenerated - + def benefit(outputDb, reactorId): """Input : sqlite output database and reactor agent id Output : cumulative sum of actualized income and expense (= - expenditures + income) @@ -724,7 +724,7 @@ def benefit(outputDb, reactorId): actualization.index = rtn.index rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn - + def lcoe(outputDb, reactorId, capital=True): """Input : sqlite output database and reactor agent id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) @@ -739,9 +739,9 @@ def lcoe(outputDb, reactorId, capital=True): actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) - + def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): - """Input : sqlite output database, reactor id, time window (t0, period) + """Input : sqlite output database, reactor id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ db = dbopen(outputDb) @@ -766,7 +766,7 @@ def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): rtn['Power'] = pd.Series() rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): + for i in range(simulationBegin + t0, simulationBegin + t0 + period): rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): @@ -777,7 +777,7 @@ def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): actualization.index = rtn.index rtn['Actualized'] = rtn['Ratio'] * actualization return rtn - + def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): """Just for tests : another way to calculate the period costs """ @@ -810,14 +810,14 @@ def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): #tmp['WasteManagement'][j] = pd.Series() rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) return rtn - + def power_generated(outputDb, reactorId): """Input : sqlite output database and reactor agent id Output : Electricity generated in MWh every year """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) - dfPower = evaler.eval('TimeSeriesPower').reset_index() + dfPower = evaler.eval('TimeSeriesPower').reset_index() dfInfo = evaler.eval('Info').reset_index() duration = dfInfo.loc[0, 'Duration'] initialYear = dfInfo.loc[0, 'InitialYear'] @@ -829,7 +829,7 @@ def power_generated(outputDb, reactorId): return rtn.fillna(0) # Institution level - + def institution_annual_costs(outputDb, institutionId, capital=True, truncate=True): """Input : sqlite output database and institution's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. Output : total reactor costs per year over its lifetime at the institution level. @@ -876,7 +876,7 @@ def institution_annual_costs(outputDb, institutionId, capital=True, truncate=Tru del costs['Capital'] costs = costs.groupby('Year').sum() return costs - + def institution_annual_costs_present_value(outputDb, reactorId, capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ @@ -884,7 +884,7 @@ def institution_annual_costs_present_value(outputDb, reactorId, capital=True): actualization = actualization_vector(len(costs)) actualization.index = costs.index return costs.apply(lambda x : x * actualization) - + def institution_benefit(outputDb, institutionId): """Input : sqlite output database and institution agent id Output : cumulative sum of income and expense (= - expenditures + income) @@ -897,9 +897,9 @@ def institution_benefit(outputDb, institutionId): actualization.index = rtn.index rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn - + def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=True): - """Input : sqlite output database, institution id, time window (t0, period) + """Input : sqlite output database, institution id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ db = dbopen(outputDb) @@ -924,7 +924,7 @@ def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=T rtn['Power'] = pd.Series() rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): + for i in range(simulationBegin + t0, simulationBegin + t0 + period): rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): @@ -935,7 +935,7 @@ def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=T actualization.index = rtn.index rtn['Actualized'] = rtn['Ratio'] * actualization return rtn - + def institution_period_costs2(outputDb, institutionId, t0=0, period=20, capital=True): """Just for tests : another method for period costs """ @@ -967,7 +967,7 @@ def institution_period_costs2(outputDb, institutionId, t0=0, period=20, capital= rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) return rtn - + def institution_power_generated(outputDb, institutionId, truncate=True): """Input : sqlite output database and institution agent id Output : Sum of electricity generated in MWh every year in the institution reactor fleet @@ -1008,7 +1008,7 @@ def institution_lcoe(outputDb, institutionId): actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) - + def institution_average_lcoe(outputDb, institutionId): """Input : sqlite output database and institution agent id @@ -1049,7 +1049,7 @@ def institution_average_lcoe(outputDb, institutionId): rtn['Power'] += rtn['Temp2'].fillna(0) rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) - + # Region level def region_annual_costs(outputDb, regionId, capital=True, truncate=True): @@ -1101,7 +1101,7 @@ def region_annual_costs(outputDb, regionId, capital=True, truncate=True): del costs['Capital'] costs = costs.groupby('Year').sum() return costs - + def region_annual_costs_present_value(outputDb, regionId, capital=True, truncate=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ @@ -1109,7 +1109,7 @@ def region_annual_costs_present_value(outputDb, regionId, capital=True, truncate actualization = actualization_vector(len(costs)) actualization.index = costs.index return costs.apply(lambda x : x * actualization) - + def region_benefit(outputDb, regionId): """Input : sqlite output database and region agent id Output : cumulative sum of actualized income and expense (= - expenditures + income) @@ -1122,9 +1122,9 @@ def region_benefit(outputDb, regionId): actualization.index = rtn.index rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn - + def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): - """Input : sqlite output database, region id, time window (t0, period) + """Input : sqlite output database, region id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ db = dbopen(outputDb) @@ -1149,7 +1149,7 @@ def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): rtn['Power'] = pd.Series() rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): + for i in range(simulationBegin + t0, simulationBegin + t0 + period): rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd + 1): @@ -1160,7 +1160,7 @@ def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): actualization.index = rtn.index rtn['Actualized'] = rtn['Ratio'] * actualization return rtn - + def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): """Just for tests : another method to calculate period costs """ @@ -1192,7 +1192,7 @@ def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) return rtn - + def region_power_generated(outputDb, regionId, truncate=True): """Input : sqlite output database and region agent id Output : Sum of electricity generated in MWh every years in the region reactor fleet @@ -1279,7 +1279,7 @@ def region_average_lcoe(outputDb, regionId): rtn['Power'] += rtn['Temp2'] rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) - + # Simulation level def simulation_annual_costs(outputDb, capital=True, truncate=True): @@ -1327,7 +1327,7 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): del costs['Capital'] costs = costs.groupby('Year').sum() return costs - + def simulation_annual_costs_present_value(outputDb, capital=True, truncate=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ @@ -1335,7 +1335,7 @@ def simulation_annual_costs_present_value(outputDb, capital=True, truncate=True) for year in df.index: df.loc[year, :] = df.loc[year, :] / (1 + default_discount_rate) ** (year - df.index[0]) return df - + def simulation_benefit(outputDb): """Input : sqlite output database Output : cumulative sum of total income and total expense (= - expenditures + income) when all reactors of the simulation are taken into account @@ -1348,9 +1348,9 @@ def simulation_benefit(outputDb): actualization.index = rtn.index rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn - + def simulation_period_costs(outputDb, t0=0, period=20, capital=True): - """Input : sqlite output database, time window (t0, period) + """Input : sqlite output database, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of total expense in [t+t0, t+t0+period] divided by total actualized power generated in [t+t0, t+t0+period] when all reactors of the simulation are taken into account """ db = dbopen(outputDb) @@ -1374,7 +1374,7 @@ def simulation_period_costs(outputDb, t0=0, period=20, capital=True): rtn['Power'] = pd.Series() rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): + for i in range(simulationBegin + t0, simulationBegin + t0 + period): rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): @@ -1382,7 +1382,7 @@ def simulation_period_costs(outputDb, t0=0, period=20, capital=True): rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) return rtn - + def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): """Just for tests : another method to calculate the period costs """ @@ -1413,7 +1413,7 @@ def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) return rtn - + def simulation_power_generated(outputDb, truncate=True): """Input : sqlite output database Output : Electricity generated in MWh every years by all the reactors of the simulation @@ -1490,4 +1490,5 @@ def simulation_average_lcoe(outputDb): rtn['Power'] += rtn['Temp2'].fillna(0) print(id) # test rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] - return rtn.fillna(0) + return rtn.fillna(0) + diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 69f44548..6b329758 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -102,14 +102,15 @@ def capital_shape(beforePeak=48, afterPeak=48): """ if (not isinstance(beforePeak, int)) or (not isinstance(afterPeak, int)): raise Exception("input parameters must be integers") - step1 = pd.Series(list(range(beforePeak))).apply( - lambda x: 2/(beforePeak*(beforePeak+afterPeak))*x) - step2 = pd.Series( - list(range(beforePeak, beforePeak + afterPeak + 1))).apply( - lambda x: -2 / afterPeak * (beforePeak + afterPeak) - * (x - - beforePeak - + afterPeak)) + step1 = pd.Series(list(range(beforePeak))) + step1 = step1.apply(lambda x: + 2 * x / (beforePeak * (beforePeak + afterPeak))) + + step2 = pd.Series(list(range(beforePeak, beforePeak + afterPeak + 1))) + step2 = step2.apply(lambda x: + -2 / (afterPeak * (beforePeak + afterPeak)) + * (x - beforePeak - afterPeak)) + return pd.concat([step1, step2]).reset_index()[0] diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 6a842fac..903e5538 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -235,6 +235,7 @@ def test_operation_maintenance(): assert_frame_equal(exp, obs) +# something is missing to be able to match the exp DataFrame.... def test_economic_info(): exp = pd.DataFrame(np.array([ (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 0, 25436.85), @@ -253,9 +254,9 @@ def test_economic_info(): 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20), ('Reactor1', 13, 9, 0.1, 0.1, 0.1, 0.1, 10, 5, 10, 1, 1, 1, 0, 0, 0, 0, 'uox', 1, 0, 0, 0, 20) - ], dtype=ensure_dt_bytes([('Agent_Prototype', 'O'), - ('Agent_AgentId', ' Date: Thu, 21 May 2020 18:17:39 -0500 Subject: [PATCH 32/64] starting xml parsing --- cymetric/eco_metrics.py | 448 +++----------------------------------- cymetric/eco_tools.py | 396 +++++++++++++++++++++++++++++++++ tests/parameters.xml | 14 +- tests/test_eco_metrics.py | 222 +++++++++---------- 4 files changed, 556 insertions(+), 524 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index ef698ede..ef4ae7df 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -58,8 +58,10 @@ def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): simDuration = dfInfo['Duration'].iloc[0] dfEntry = pd.DataFrame([dfEntry.EnterTime, dfEntry.AgentId]).transpose() rtn = pd.DataFrame() + print(dfEcoInfo) for index, eco_row in dfEcoInfo.iterrows(): id = eco_row['AgentId'] + print(id) if isreactor(dfPower, id): deviation = eco_row['Capital_Deviation'] * np.random.randn(1) deviation = int(np.around(deviation)) @@ -237,417 +239,31 @@ def operation_maintenance(dfPower, dfEcoInfo): _eideps = ['AgentEntry'] -_eischema = [('Agent_Prototype', ts.STRING), - ('Agent_AgentId', ts.INT), - ('Agent_ParentId', ts.INT), - ('Finance_ReturnOnDebt', ts.DOUBLE), - ('Finance_ReturnOnEquity', ts.DOUBLE), - ('Finance_TaxRate', ts.DOUBLE), - ('Finance_DiscountRate', ts.DOUBLE), - ('Capital_beforePeak', ts.INT), - ('Capital_afterPeak', ts.INT), - ('Capital_constructionDuration', ts.INT), +_eischema = [('Prototype', ts.STRING), + ('AgentId', ts.INT), + ('ParentId', ts.INT), + ('ReturnOnDebt', ts.DOUBLE), + ('ReturnOnEquity', ts.DOUBLE), + ('TaxRate', ts.DOUBLE), + ('DiscountRate', ts.DOUBLE), + ('beforePeak', ts.INT), + ('afterPeak', ts.INT), + ('constructionDuration', ts.INT), ('Capital_Deviation', ts.DOUBLE), - ('Capital_OvernightCost', ts.DOUBLE), - ('Decommissioning_Duration', ts.INT), - ('Decommissioning_OvernightCost', ts.DOUBLE), - ('OperationMaintenance_FixedCost', ts.DOUBLE), - ('OperationMaintenance_VariableCost', ts.DOUBLE), + ('OvernightCost', ts.DOUBLE), + ('Duration', ts.INT), + ('OvernightCost', ts.DOUBLE), + ('FixedCost', ts.DOUBLE), + ('VariableCost', ts.DOUBLE), ('OperationMaintenance_Deviation', ts.DOUBLE), ('FuelCommodity', ts.STRING), - ('Fuel_SupplyCost', ts.DOUBLE), - ('Fuel_WasteFee', ts.DOUBLE), + ('SupplyCost', ts.DOUBLE), + ('WasteFee', ts.DOUBLE), ('Fuel_Deviation', ts.DOUBLE), ('Truncation_Begin', ts.INT), ('Truncation_End', ts.INT)] -@metric(name='EconomicInfo', depends=_eideps, schema=_eischema) -def economic_info(series): - """The EconomicInfo metric stores all economic data needed to calculate the - economic metrics. These economic parameters are originally written in - 'parameters.xml'. - """ - tuples = ['Agent_Prototype', - 'Agent_AgentId', - 'Agent_ParentId', - 'Finance_ReturnOnDebt', - 'Finance_ReturnOnEquity', - 'Finance_TaxRate', - 'Finance_DiscountRate', - 'Captial_beforePeak', - 'Captial_afterPeak', - 'Captial_constructionDuration', - 'Captial_Deviation', - 'Captial_OvernightCost', - 'Decommissioning_Duration', - 'Decommissioning_OvernightCost', - 'OperationMaintenance_FixedCost', - 'OperationMaintenance_VariableCost', - 'OperationMaintenance_Deviation', - 'Fuel_Commodity', - 'Fuel_SupplyCost', - 'Fuel_WasteFee', - 'Fuel_Deviation', - 'Truncation_Begin', - 'Truncation_End'] - index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) - rtn = pd.DataFrame(index=index) - dfEntry = series[0].reset_index() - agentIndex = dfEntry.reset_index().set_index('AgentId')['index'] - rtn = rtn.T - rtn['Agent_Prototype'] = dfEntry['Prototype'] - rtn['Agent_AgentId'] = dfEntry['AgentId'] - rtn['Agent_ParentId'] = dfEntry['ParentId'] - parametersInput = 'parameters.xml' - tree = ET.parse(parametersInput) - root = tree.getroot() - truncation = root.find('truncation') - rtn['Truncation_Begin'] = int(truncation.find('simulation_begin').text) - rtn['Truncation_End'] = int(truncation.find('simulation_end').text) - finance = root.find('finance') - if finance is not None: - rtn.loc[:, 'Finance_TaxRate'] = float(finance.find('tax_rate').text) - rtn.loc[:, 'Finance_ReturnOnDebt'] = float(finance.find('return_on_debt').text) - rtn.loc[:, 'Finance_ReturnOnEquity'] = float(finance.find('return_on_equity').text) - rtn.loc[:, 'Finance_DiscountRate'] = float(finance.find('discount_rate').text) - capital = root.find('capital') - if capital is not None: - rtn.loc[:, 'Capital_beforePeak'] = int(capital.find('beforePeak').text) - rtn.loc[:, 'Capital_afterPeak'] = int(capital.find('afterPeak').text) - rtn.loc[:, 'Capital_constructionDuration'] = int(capital.find('constructionDuration').text) - rtn.loc[:, 'Capital_Deviation'] = float(capital.find('deviation').text) - rtn.loc[:, 'Capital_OvernightCost'] = float(capital.find('overnight_cost').text) - decommissioning = root.find('decommissioning') - if decommissioning is not None: - rtn.loc[:, 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) - rtn.loc[:, 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) - operation_maintenance = root.find('operation_maintenance') - if operation_maintenance is not None: - rtn.loc[:, 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) - rtn.loc[:, 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) - rtn.loc[:, 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) - fuel = root.find('fuel') - indexCopy = rtn.index.copy() - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - for j in indexCopy: - if np.isnan(rtn.loc[j, 'Fuel_SupplyCost']): - rtn.loc[j, 'Fuel_Commodity'] = name - rtn.loc[j, 'Fuel_SupplyCost'] = supply - rtn.loc[j, 'Fuel_WasteFee'] = waste - rtn.loc[j, 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[j] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for region in root.findall('region'): - idRegion = int(region.find('id').text) - finance = region.find('finance') - if finance is not None: - returnOnDebt = float(finance.find('return_on_debt').text) - returnOnEquity = float(finance.find('return_on_equity').text) - taxRate = float(finance.find('tax_rate').text) - discountRate = float(finance.find('discount_rate').text) - rtn.loc[agentIndex[idRegion], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idRegion], 'Finance_DiscountRate'] = discountRate - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate - capital = region.find('capital') - if capital is not None: - beforePeak = int(capital.find('beforePeak').text) - afterPeak = int(capital.find('afterPeak').text) - constructionDuration = int(capital.find('constructionDuration').text) - deviation = float(capital.find('deviation').text) - overnightCost = float(capital.find('overnight_cost').text) - rtn.loc[agentIndex[idRegion], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idRegion], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idRegion], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idRegion], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idRegion], 'Captial_OvernightCost'] = overnightCost - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost - decommissioning = region.find('decommissioning') - if decommissioning is not None: - duration = int(decommissioning.find('duration').text) - overnightCost = float(decommissioning.find('overnight_cost').text) - rtn.loc[agentIndex[idRegion], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idRegion], 'Decommissioning_OvernightCost'] = overnightCost - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost - operation_maintenance = region.find('operation_maintenance') - if operation_maintenance is not None: - fixed = float(operation_maintenance.find('fixed').text) - variable = float(operation_maintenance.find('variable').text) - deviation = float(operation_maintenance.find('deviation').text) - rtn.loc[agentIndex[idRegion], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idRegion], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idRegion], 'OperationMaintenance_Deviation'] = deviation - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - fuel = region.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idRegion], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idRegion], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idRegion], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idRegion]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for institution in region.findall('institution'): - idInstitution = int(institution.find('id').text) - finance = institution.find('finance') - if finance is not None: - returnOnDebt = float(finance.find('return_on_debt').text) - returnOnEquity = float(finance.find('return_on_equity').text) - taxRate = float(finance.find('tax_rate').text) - discountRate = float(finance.find('discount_rate').text) - rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idInstitution],'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt - rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity - rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate - capital = institution.find('capital') - if capital is not None: - beforePeak = int(capital.find('beforePeak').text) - afterPeak = int(capital.find('afterPeak').text) - constructionDuration = int(capital.find('constructionDuration').text) - deviation = float(capital.find('deviation').text) - overnightCost = float(capital.find('overnight_cost').text) - rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost - decommissioning = institution.find('decommissioning') - if decommissioning is not None: - duration = int(decommissioning.find('duration').text) - overnightCost = float(decommissioning.find('overnight_cost').text) - rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost - operation_maintenance = institution.find('operation_maintenance') - if operation_maintenance is not None: - fixed = float(operation_maintenance.find('fixed').text) - variable = float(operation_maintenance.find('variable').text) - deviation = float(operation_maintenance.find('deviation').text) - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - fuel = institution.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - for prototype in institution.findall('prototype'): - name = prototype.find('name').text - tmp = dfEntry[dfEntry.ParentId==idInstitution] - facilityIdList = tmp[tmp.Prototype==name].loc[:,'AgentId'].tolist() - capital = prototype.find('capital') - if capital is not None: - beforePeak = int(capital.find('beforePeak').text) - afterPeak = int(capital.find('afterPeak').text) - constructionDuration = int(capital.find('constructionDuration').text) - deviation = float(capital.find('deviation').text) - overnight = float(capital.find('overnight_cost').text) - for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnight - operation_maintenance = prototype.find('operation_maintenance') - if operation_maintenance is not None: - fixed = float(operation_maintenance.find('fixed').text) - variable = float(operation_maintenance.find('variable').text) - deviation = float(operation_maintenance.find('deviation').text) - for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - fuel = prototype.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - for idFacility in facilityIdList: - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - decommissioning = prototype.find('decommissioning') - if decommissioning is not None: - duration = int(decommissioning.find('duration').text) - overnight = float(decommissioning.find('overnight_cost').text) - for idFacility in facilityIdList: - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnight - for facility in prototype.findall('facility'): - idFacility = int(facility.find('id').text) - capital = facility.find('capital') - if capital is not None: - rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = int(capital.find('beforePeak').text) - rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = int(capital.find('afterPeak').text) - rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = int(capital.find('constructionDuration').text) - rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = float(capital.find('deviation').text) - rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = float(capital.find('overnight_cost').text) - operation_maintenance = facility.find('operation_maintenance') - if operation_maintenance is not None: - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) - rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) - fuel = facility.find('fuel') - if fuel is not None: - for type in fuel.findall('type'): - supply = float(type.find('supply_cost').text) - waste = float(type.find('waste_fee').text) - name = type.find('name').text - deviation = float(type.find('deviation').text) - if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - else: - indice = rtn.index.size - rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - rtn.loc[indice, 'Fuel_Commodity'] = name - rtn.loc[indice, 'Fuel_SupplyCost'] = supply - rtn.loc[indice, 'Fuel_WasteFee'] = waste - rtn.loc[indice, 'Fuel_Deviation'] = deviation - decommissioning = facility.find('decommissioning') - if decommissioning is not None: - rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) - rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) - return rtn - - -del _eideps, _eischema """The functions below aim at calculating more complex metrics than the simple cash flows corresponding to the construction, fuel, O&M and decommissioning costs. The metrics can be calculated at an agent, institution, region or simulation level. @@ -665,13 +281,17 @@ def annual_costs(outputDb, reactorId, capital=True): """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEntry = evaler.eval('AgentEntry').reset_index() + + dfInfo = evaler.eval('Info') + duration = dfInfo['Duration'].iloc[0] + initialYear = dfInfo['InitialYear'].iloc[0] + initialMonth = dfInfo['InitialMonth'].iloc[0] + + dfEntry = evaler.eval('AgentEntry') + print(dfEntry) commissioning = dfEntry[dfEntry.AgentId==reactorId]['EnterTime'].iloc[0] - dfCapitalCosts = evaler.eval('CapitalCost').reset_index() + dfCapitalCosts = evaler.eval('CapitalCost') + print(dfCapitalCosts) dfCapitalCosts = dfCapitalCosts[dfCapitalCosts.AgentId==reactorId].copy() dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() costs = pd.DataFrame({'Capital' : dfCapitalCosts['Payment']}, index=list(range(duration))) @@ -679,11 +299,11 @@ def annual_costs(outputDb, reactorId, capital=True): dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts.AgentId==reactorId].copy() dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] - dfOMCosts = evaler.eval('OperationMaintenance').reset_index() + dfOMCosts = evaler.eval('OperationMaintenance') dfOMCosts = dfOMCosts[dfOMCosts.AgentId==reactorId].copy() dfOMCosts = dfOMCosts.groupby('Time').sum() costs['OandM'] = dfOMCosts['Payment'] - dfFuelCosts = evaler.eval('FuelCost').reset_index() + dfFuelCosts = evaler.eval('FuelCost') dfFuelCosts = dfFuelCosts[dfFuelCosts.AgentId==reactorId].copy() dfFuelCosts = dfFuelCosts.groupby('Time').sum() costs['Fuel'] = dfFuelCosts['Payment'] @@ -837,9 +457,9 @@ def institution_annual_costs(outputDb, institutionId, capital=True, truncate=Tru db = dbopen(outputDb) evaler = Evaluator(db, write=False) dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] + duration = dfInfo['Duration'].iloc[0] + initialYear = dfInfo['InitialYear'].iloc[0] + initialMonth = dfInfo['InitialMonth'].iloc[0] dfEcoInfo = evaler.eval('EconomicInfo') simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 6b329758..a1186845 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -7,9 +7,405 @@ import pandas as pd import numpy as np +import xml.etree.ElementTree as ET import math +class eco_input_data(): + """The EconomicInfo metric stores all economic data needed to calculate the + economic metrics. These economic parameters are originally written in + 'parameters.xml'. + """ + + def __init__(self, filename): + self.load_economic_info(filename) + + def unload_group(self, xml_group): + group_dict = {} + if xml_group is not None: + for child in xml_group: + group_dict[child.tag] = float(child.text) + return group_dict + + + def get_dict_per_key(self, tree, key): + xml_group = tree.find(key) + return self.unload_group(xml_group) + + def get_fuels(self, tree): + xml_group = tree.find('fuel') + fuels = {} + if xml_group is not None: + for xml_subgroup in xml_group.findall('type'): + fuels[xml_subgroup.attrib["name"]] = self.unload_group(xml_subgroup) + return fuels + + def load_economic_info(self, eco_input): + tree = ET.parse(eco_input) + root = tree.getroot() + + # start and end of economics consideration + self.periode = self.get_dict_per_key(root, "truncation") + + # Economic golbal paramter + self.finance = self.get_dict_per_key(root, "finance") + self.capital = self.get_dict_per_key(root, "capital") + self.decommission = self.get_dict_per_key(root, "decommissioning") + self.operation = self.get_dict_per_key(root, "operation_maintenance") + self.fuels = self.get_fuels(root) + print(self.periode) + print(self.finance) + print(self.capital) + print(self.decommission) + print(self.operation) + print(self.fuels) + + +def load_economic_info(eco_input): + tuples = ['Prototype', + 'AgentId', + 'ReturnOnDebt', + 'ReturnOnEquity', + 'TaxRate', + 'DiscountRate', + 'beforePeak', + 'afterPeak', + 'constructionDuration', + 'Captial_Deviation', + 'OvernightCost', + 'Duration', + 'OvernightCost', + 'FixedCost', + 'VariableCost', + 'OperationMaintenance_Deviation', + 'Commodity', + 'SupplyCost', + 'WasteFee', + 'Fuel_Deviation', + 'Begin', + 'End'] + #rtn = pd.DataFrame(index=tuples) + #agentIndex = dfEntry.reset_index().set_index('AgentId')['index'] + #rtn = rtn.T + #rtn['Agent_Prototype'] = dfEntry['Prototype'] + #rtn['Agent_AgentId'] = dfEntry['AgentId'] + #rtn['Agent_ParentId'] = dfEntry['ParentId'] + #parametersInput = 'tests/parameters.xml' + #for child in root: + # print(child.tag, child.attrib) + # + #def add_finance(rtn, root): + + + #def add_capital(rtn, root): + #def add_decommisioning(rtn, root): + + #def add_operation_maintenance(rtn, root): + + #def add_fuel(rtn, root): + # + #add_finance(rtn, root) + + + # for region in root.findall('region'): + # idRegion = int(region.find('id').text) + # finance = region.find('finance') + # if finance is not None: + # returnOnDebt = float(finance.find('return_on_debt').text) + # returnOnEquity = float(finance.find('return_on_equity').text) + # taxRate = float(finance.find('tax_rate').text) + # discountRate = float(finance.find('discount_rate').text) + # rtn.loc[agentIndex[idRegion], 'Finance_TaxRate'] = taxRate + # rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnDebt'] = returnOnDebt + # rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnEquity'] = returnOnEquity + # rtn.loc[gent_index[idRegion], 'Finance_DiscountRate'] = discountRate + # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + # rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate + # rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt + # rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnEquity'] = returnOnEquity + # rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate + # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt + # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity + # rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate + # capital = region.find('capital') + # if capital is not None: + # beforePeak = int(capital.find('beforePeak').text) + # afterPeak = int(capital.find('afterPeak').text) + # constructionDuration = int(capital.find('constructionDuration').text) + # deviation = float(capital.find('deviation').text) + # overnightCost = float(capital.find('overnight_cost').text) + # rtn.loc[agentIndex[idRegion], 'Captial_beforePeak'] = beforePeak + # rtn.loc[agentIndex[idRegion], 'Captial_afterPeak'] = afterPeak + # rtn.loc[agentIndex[idRegion], 'Captial_constructionDuration'] = constructionDuration + # rtn.loc[agentIndex[idRegion], 'Captial_Deviation'] = deviation + # rtn.loc[agentIndex[idRegion], 'Captial_OvernightCost'] = overnightCost + # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + # rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak + # rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak + # rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration + # rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation + # rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + # rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak + # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost + # decommissioning = region.find('decommissioning') + # if decommissioning is not None: + # duration = int(decommissioning.find('duration').text) + # overnightCost = float(decommissioning.find('overnight_cost').text) + # rtn.loc[agentIndex[idRegion], 'Decommissioning_Duration'] = duration + # rtn.loc[agentIndex[idRegion], 'Decommissioning_OvernightCost'] = overnightCost + # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + # rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration + # rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost + # operation_maintenance = region.find('operation_maintenance') + # if operation_maintenance is not None: + # fixed = float(operation_maintenance.find('fixed').text) + # variable = float(operation_maintenance.find('variable').text) + # deviation = float(operation_maintenance.find('deviation').text) + # rtn.loc[agentIndex[idRegion], 'OperationMaintenance_FixedCost'] = fixed + # rtn.loc[agentIndex[idRegion], 'OperationMaintenance_VariableCost'] = variable + # rtn.loc[agentIndex[idRegion], 'OperationMaintenance_Deviation'] = deviation + # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed + # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable + # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation + # fuel = region.find('fuel') + # if fuel is not None: + # for type in fuel.findall('type'): + # supply = float(type.find('supply_cost').text) + # waste = float(type.find('waste_fee').text) + # name = type.find('name').text + # deviation = float(type.find('deviation').text) + # if np.isnan(rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idRegion], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idRegion], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idRegion], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idRegion]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): + # if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # for institution in region.findall('institution'): + # idInstitution = int(institution.find('id').text) + # finance = institution.find('finance') + # if finance is not None: + # returnOnDebt = float(finance.find('return_on_debt').text) + # returnOnEquity = float(finance.find('return_on_equity').text) + # taxRate = float(finance.find('tax_rate').text) + # discountRate = float(finance.find('discount_rate').text) + # rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate + # rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt + # rtn.loc[agentIndex[idInstitution],'Finance_ReturnOnEquity'] = returnOnEquity + # rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate + # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt + # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity + # rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate + # capital = institution.find('capital') + # if capital is not None: + # beforePeak = int(capital.find('beforePeak').text) + # afterPeak = int(capital.find('afterPeak').text) + # constructionDuration = int(capital.find('constructionDuration').text) + # deviation = float(capital.find('deviation').text) + # overnightCost = float(capital.find('overnight_cost').text) + # rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak + # rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak + # rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration + # rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation + # rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost + # decommissioning = institution.find('decommissioning') + # if decommissioning is not None: + # duration = int(decommissioning.find('duration').text) + # overnightCost = float(decommissioning.find('overnight_cost').text) + # rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration + # rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost + # operation_maintenance = institution.find('operation_maintenance') + # if operation_maintenance is not None: + # fixed = float(operation_maintenance.find('fixed').text) + # variable = float(operation_maintenance.find('variable').text) + # deviation = float(operation_maintenance.find('deviation').text) + # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed + # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable + # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation + # fuel = institution.find('fuel') + # if fuel is not None: + # for type in fuel.findall('type'): + # supply = float(type.find('supply_cost').text) + # waste = float(type.find('waste_fee').text) + # name = type.find('name').text + # deviation = float(type.find('deviation').text) + # if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): + # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # for prototype in institution.findall('prototype'): + # name = prototype.find('name').text + # tmp = dfEntry[dfEntry.ParentId==idInstitution] + # facilityIdList = tmp[tmp.Prototype==name].loc[:,'AgentId'].tolist() + # capital = prototype.find('capital') + # if capital is not None: + # beforePeak = int(capital.find('beforePeak').text) + # afterPeak = int(capital.find('afterPeak').text) + # constructionDuration = int(capital.find('constructionDuration').text) + # deviation = float(capital.find('deviation').text) + # overnight = float(capital.find('overnight_cost').text) + # for idFacility in facilityIdList: + # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak + # rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak + # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration + # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation + # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnight + # operation_maintenance = prototype.find('operation_maintenance') + # if operation_maintenance is not None: + # fixed = float(operation_maintenance.find('fixed').text) + # variable = float(operation_maintenance.find('variable').text) + # deviation = float(operation_maintenance.find('deviation').text) + # for idFacility in facilityIdList: + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation + # fuel = prototype.find('fuel') + # if fuel is not None: + # for type in fuel.findall('type'): + # supply = float(type.find('supply_cost').text) + # waste = float(type.find('waste_fee').text) + # name = type.find('name').text + # deviation = float(type.find('deviation').text) + # for idFacility in facilityIdList: + # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # decommissioning = prototype.find('decommissioning') + # if decommissioning is not None: + # duration = int(decommissioning.find('duration').text) + # overnight = float(decommissioning.find('overnight_cost').text) + # for idFacility in facilityIdList: + # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration + # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnight + # for facility in prototype.findall('facility'): + # idFacility = int(facility.find('id').text) + # capital = facility.find('capital') + # if capital is not None: + # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = int(capital.find('beforePeak').text) + # rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = int(capital.find('afterPeak').text) + # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = int(capital.find('constructionDuration').text) + # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = float(capital.find('deviation').text) + # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = float(capital.find('overnight_cost').text) + # operation_maintenance = facility.find('operation_maintenance') + # if operation_maintenance is not None: + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) + # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) + # fuel = facility.find('fuel') + # if fuel is not None: + # for type in fuel.findall('type'): + # supply = float(type.find('supply_cost').text) + # waste = float(type.find('waste_fee').text) + # name = type.find('name').text + # deviation = float(type.find('deviation').text) + # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): + # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name + # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply + # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste + # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation + # else: + # indice = rtn.index.size + # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] + # rtn.loc[indice, 'Fuel_Commodity'] = name + # rtn.loc[indice, 'Fuel_SupplyCost'] = supply + # rtn.loc[indice, 'Fuel_WasteFee'] = waste + # rtn.loc[indice, 'Fuel_Deviation'] = deviation + # decommissioning = facility.find('decommissioning') + # if decommissioning is not None: + # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) + # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) + #return rtn + + #################### # Mining & Milling # #################### diff --git a/tests/parameters.xml b/tests/parameters.xml index ab4e14f6..406f7935 100644 --- a/tests/parameters.xml +++ b/tests/parameters.xml @@ -39,6 +39,18 @@ + + + 1 + 0 + 0 + + + 2 + 0 + 0 + + 0.1 @@ -52,4 +64,4 @@ 20 - \ No newline at end of file + diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 903e5538..ed46ec3e 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -11,7 +11,7 @@ import pandas as pd from pandas.util.testing import assert_frame_equal -from cymetric import eco_metrics +from cymetric import eco_metrics, eco_tools from cymetric.tools import raw_to_series, ensure_dt_bytes @@ -236,70 +236,70 @@ def test_operation_maintenance(): # something is missing to be able to match the exp DataFrame.... -def test_economic_info(): - exp = pd.DataFrame(np.array([ - (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 0, 25436.85), - (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 2, 25436.85), - (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 5, 8, 43800.0) - ], dtype=ensure_dt_bytes([ - ('SimId', 'O'), ('AgentId', ' Date: Thu, 21 May 2020 18:35:46 -0500 Subject: [PATCH 33/64] swtiching to yml parsing --- cymetric/eco_tools.py | 43 +++++---------------------------------- tests/test_eco_metrics.py | 2 +- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index a1186845..d43c9bc0 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -7,7 +7,7 @@ import pandas as pd import numpy as np -import xml.etree.ElementTree as ET +import yaml import math @@ -20,45 +20,12 @@ class eco_input_data(): def __init__(self, filename): self.load_economic_info(filename) - def unload_group(self, xml_group): - group_dict = {} - if xml_group is not None: - for child in xml_group: - group_dict[child.tag] = float(child.text) - return group_dict - - - def get_dict_per_key(self, tree, key): - xml_group = tree.find(key) - return self.unload_group(xml_group) - - def get_fuels(self, tree): - xml_group = tree.find('fuel') - fuels = {} - if xml_group is not None: - for xml_subgroup in xml_group.findall('type'): - fuels[xml_subgroup.attrib["name"]] = self.unload_group(xml_subgroup) - return fuels def load_economic_info(self, eco_input): - tree = ET.parse(eco_input) - root = tree.getroot() - - # start and end of economics consideration - self.periode = self.get_dict_per_key(root, "truncation") - - # Economic golbal paramter - self.finance = self.get_dict_per_key(root, "finance") - self.capital = self.get_dict_per_key(root, "capital") - self.decommission = self.get_dict_per_key(root, "decommissioning") - self.operation = self.get_dict_per_key(root, "operation_maintenance") - self.fuels = self.get_fuels(root) - print(self.periode) - print(self.finance) - print(self.capital) - print(self.decommission) - print(self.operation) - print(self.fuels) + stream = open(eco_input) + data = yaml.load(stream, Loader=yaml.FullLoader) + self.dict = data + print("mydict", self.dict) def load_economic_info(eco_input): diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index ed46ec3e..c860fca2 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -310,7 +310,7 @@ def test_operation_maintenance(): def test_xml_parsing(): - eco_info = eco_tools.eco_input_data("tests/parameters.xml") + eco_info = eco_tools.eco_input_data("tests/parameters.yml") def test_annual_costs(): From bcfb2b730e366285324e8382a717238e49eca02e Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 21 May 2020 18:36:04 -0500 Subject: [PATCH 34/64] adding a sample of the yaml file --- tests/parameters.yml | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/parameters.yml diff --git a/tests/parameters.yml b/tests/parameters.yml new file mode 100644 index 00000000..483e1f61 --- /dev/null +++ b/tests/parameters.yml @@ -0,0 +1,85 @@ +eco_model: + + periode: + start: 0 + end: 20 + + finance: + discount_rate: 0.1 + tax_rate: 0.1 + return_on_debt: 0.1 + return_on_equity: 0.1 + + capital: + deviation: 0 + beforePeak: 10 + afterPeak: 5 + constructionDuration: 10 + overnight_cost: 1 + + operation_maintenance: + fixed: 1 + variable: 1 + deviation: 0 + + decommission: + duration: 5 + overnight_cost: 1 + + fuels: + - name: uox + supply_cost: 1 + waste_fee: 0 + deviation: 0 + + - name: mox + supply_cost: 2 + supply_fee: 0 + deviation: 0 + + region: + - prototype: myRegion + + finance: + discount_rate: 0.1 + tax_rate: 0.1 + return_on_debt: 0.1 + return_on_equity: 0.1 + + capital: + deviation: 0 + beforePeak: 10 + afterPeak: 5 + constructionDuration: 10 + overnight_cost: 1 + + operation_maintenance: + fixed: 1 + variable: 1 + deviation: 0 + + fuels: + - name: uox + supply_cost: 1.5 + waste_fee: 0 + deviation: 0 + + institution: + - prototype: myInstitution + + capital: + deviation: 0 + beforePeak: 10 + afterPeak: 5 + constructionDuration: 10 + overnight_cost: 1 + + fuels: + - name: uox + supply_cost: 2.5 + waste_fee: 0 + deviation: 0 + + + + From 0c6fe19ecd6c1750df27b6d0a694085602e8164f Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 22 May 2020 10:48:41 -0500 Subject: [PATCH 35/64] yaml reader working --- cymetric/eco_tools.py | 66 ++++++++++++++++++++++++++++++++++++--- tests/parameters.yml | 22 +++++++++---- tests/test_eco_metrics.py | 14 +++++++++ 3 files changed, 92 insertions(+), 10 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index d43c9bc0..f37e18c4 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -10,22 +10,80 @@ import yaml import math +eco_props_agents = ["capital", + "operation_maintenance", + "decomission", + "fuels"] +eco_props_region = ["finance"] + eco_props_agents +eco_properties = ["periode"] + eco_props_region -class eco_input_data(): + +class eco_input_data(): """The EconomicInfo metric stores all economic data needed to calculate the economic metrics. These economic parameters are originally written in 'parameters.xml'. """ - + def __init__(self, filename): self.load_economic_info(filename) - def load_economic_info(self, eco_input): stream = open(eco_input) data = yaml.load(stream, Loader=yaml.FullLoader) self.dict = data - print("mydict", self.dict) + + def get_filiation(self, name, dfEntry): + filiation = [] + filiation.append(name) + parent_id = dfEntry[dfEntry["Prototype"] == name]["ParentId"][0] + + while parent_id != -1: + # get the parent + parent_entry = dfEntry[dfEntry["AgentId"] == parent_id] + parent_name = parent_entry.iloc[0]["Prototype"] + filiation.append(parent_name) + # get the parent of the parent + parent_id = parent_entry.iloc[0]["ParentId"] + return list(reversed(filiation)) + + def update_prop(self, proto, traveling_dict, key, properties, prop_list): + updated = False + if key in traveling_dict: + for agent in traveling_dict[key]: + if agent["prototype"] == proto: + traveling_dict = agent + updated = True + for prop in prop_list: + if prop in traveling_dict: + properties[prop] = traveling_dict[prop] + return updated, traveling_dict + + def get_prototype_eco(self, name, filiation): + proto_eco = {} + traveling_dict = self.dict["eco_model"] + for prop in eco_properties: + if prop in traveling_dict: + proto_eco[prop] = traveling_dict[prop] + + for proto in filiation: + updated = False + status, traveling_dict = self.update_prop(proto, traveling_dict, + "region", proto_eco, + eco_props_region) + if not updated: + status, traveling_dict = self.update_prop(proto, + traveling_dict, + "institution", + proto_eco, + eco_props_agents) + if not updated: + status, traveling_dict = self.update_prop(proto, + traveling_dict, + "facility", + proto_eco, + eco_props_agents) + + return proto_eco def load_economic_info(eco_input): diff --git a/tests/parameters.yml b/tests/parameters.yml index 483e1f61..15548e9f 100644 --- a/tests/parameters.yml +++ b/tests/parameters.yml @@ -38,11 +38,11 @@ eco_model: deviation: 0 region: - - prototype: myRegion + - prototype: MyReg finance: discount_rate: 0.1 - tax_rate: 0.1 + tax_rate: 0.2 return_on_debt: 0.1 return_on_equity: 0.1 @@ -54,8 +54,8 @@ eco_model: overnight_cost: 1 operation_maintenance: - fixed: 1 - variable: 1 + fixed: 3 + variable: 2 deviation: 0 fuels: @@ -65,12 +65,12 @@ eco_model: deviation: 0 institution: - - prototype: myInstitution + - prototype: MyInst capital: deviation: 0 beforePeak: 10 - afterPeak: 5 + afterPeak: 75 constructionDuration: 10 overnight_cost: 1 @@ -80,6 +80,16 @@ eco_model: waste_fee: 0 deviation: 0 + institution: + - prototype: Reactor1 + + fuels: + - name: uox + supply_cost: 10.5 + waste_fee: 0 + deviation: 0 + + diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index c860fca2..e998d83a 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -311,7 +311,21 @@ def test_operation_maintenance(): def test_xml_parsing(): eco_info = eco_tools.eco_input_data("tests/parameters.yml") + entry = pd.DataFrame(np.array([ + (1, 10, 2, 13, ':cycamore:Reactor', 'Reactor1'), + (1, 10, 1, 2, 'SingleInstitution', 'MyInst'), + (1, 10, -1, 1, 'SingleRegion', 'MyReg') + ], dtype=ensure_dt_bytes([ + ('EnterTime', ' Date: Tue, 26 May 2020 08:28:47 -0500 Subject: [PATCH 36/64] capital_cost uses the new eco datas --- cymetric/eco_metrics.py | 87 ++++----- cymetric/eco_tools.py | 378 ++------------------------------------ tests/parameters.yml | 4 +- tests/test_eco_metrics.py | 23 +-- 4 files changed, 73 insertions(+), 419 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index ef4ae7df..56913be0 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -19,14 +19,14 @@ from cymetric.tools import dbopen, merge from cymetric.evaluator import Evaluator from cymetric.eco_tools import actualization_vector, isreactor, \ - capital_shape + capital_shape, get_filiation_per_id, eco_input_data from cymetric.evaluator import register_metric except ImportError: # some wacky CI paths prevent absolute importing, try relative from .metrics import metric from .evaluator import register_metric from .eco_tools import capital_shape, isreactor, actualization_vector, \ - isreactor + isreactor, get_filiation_per_id, eco_input_data from .tools import dbopen, merge from .evaluator import Evaluator @@ -38,9 +38,10 @@ # The actual metrics ## +eco_data = None -_ccdeps = ['TimeSeriesPower', 'AgentEntry', 'Info', 'EconomicInfo'] +_ccdeps = ['TimeSeriesPower', 'AgentEntry', 'Info'] _ccschema = [ ('SimId', ts.UUID), @@ -50,50 +51,52 @@ @metric(name='CapitalCost', depends=_ccdeps, schema=_ccschema) -def capital_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): +def capital_cost(dfPower, dfEntry, dfInfo): """The CapitalCost metric gives the cash flows at each time step corresponding to the reactors construction costs. """ + if eco_data is None: + print("Warning! No economical data, please load one!") + return None simDuration = dfInfo['Duration'].iloc[0] - dfEntry = pd.DataFrame([dfEntry.EnterTime, dfEntry.AgentId]).transpose() rtn = pd.DataFrame() - print(dfEcoInfo) - for index, eco_row in dfEcoInfo.iterrows(): - id = eco_row['AgentId'] - print(id) - if isreactor(dfPower, id): - deviation = eco_row['Capital_Deviation'] * np.random.randn(1) - deviation = int(np.around(deviation)) - - beforePeak = int(eco_row['Capital_beforePeak'] + deviation) - afterPeak = int(eco_row['Capital_afterPeak']) - cashFlowShape = capital_shape(beforePeak, afterPeak) - - constructionDuration = int(eco_row['Capital_constructionDuration'] - + deviation) - - powerCapacity = max(dfPower[dfPower.AgentId == id]['Value']) - overnightCost = eco_row['Capital_OvernightCost'] - cashFlow = np.around(cashFlowShape - * overnightCost - * powerCapacity, 4) - - discountRate = eco_row['Finance_DiscountRate'] - cashFlow *= ((1 + discountRate) - ** math.ceil((beforePeak + afterPeak) / 12) - - 1) / (discountRate - * math.ceil((beforePeak + afterPeak) / 12)) - - entry_time = dfEntry[dfEntry['AgentId'] == id].EnterTime.values[0] - TimeSerie = list(range(beforePeak + afterPeak + 1)) - TimeSerie += entry_time - constructionDuration - - tmp = pd.DataFrame(data={'AgentId': id, - 'Time': TimeSerie, - 'Payment': cashFlow}, - columns=['AgentId', 'Time', 'Payment']) - rtn = pd.concat([rtn, tmp], ignore_index=False) + for index, power_row in dfPower.iterrows(): + agent_id = power_row['AgentId'] + filiation = get_filiation_per_id(agent_id, dfEntry) + agent_eco_prop = eco_data.get_prototype_eco(filiation) + + deviation = float(agent_eco_prop["capital"]["deviation"]) + deviation *= np.random.randn(1) + deviation = int(np.around(deviation)) + + beforePeak = int(agent_eco_prop["capital"]["beforePeak"]) + deviation + afterPeak = int(agent_eco_prop["capital"]["afterPeak"]) + cashFlowShape = capital_shape(beforePeak, afterPeak) + + constructionDuration = int( + agent_eco_prop["capital"]['constructionDuration']) + deviation + + powerCapacity = power_row['Value'] + overnightCost = float(agent_eco_prop["capital"]['overnight_cost']) + cashFlow = np.around(cashFlowShape + * overnightCost + * powerCapacity, 4) + + discountRate = agent_eco_prop["finance"]['discount_rate'] + cashFlow *= ((1 + discountRate) + ** math.ceil((beforePeak + afterPeak) / 12) - + 1) / (discountRate + * math.ceil((beforePeak + afterPeak) / 12)) + entry_time = dfEntry[ + dfEntry['AgentId'] == agent_id].iloc[0]["EnterTime"] + TimeSerie = list(range(beforePeak + afterPeak + 1)) + TimeSerie += entry_time - constructionDuration + tmp = pd.DataFrame(data={'AgentId': agent_id, + 'Time': TimeSerie, + 'Payment': cashFlow}, + columns=['AgentId', 'Time', 'Payment']) + rtn = pd.concat([rtn, tmp], ignore_index=False) rtn['SimId'] = dfPower['SimId'].iloc[0] rtn = rtn[rtn['Time'].apply(lambda x: x >= 0 and x < simDuration)] @@ -175,13 +178,11 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): dfEntry = dfEntry[dfEntry['Lifetime'].apply(lambda x: x > 0)] reactorsId = dfEntry[dfEntry['Spec'].apply( lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - print(reactorsId) rtn = pd.DataFrame() for id in reactorsId: tmp = dfEcoInfo[dfEntry['AgentId'] == id] if(len(tmp) == 1): duration = int(tmp.at[0, 'Decommissioning_Duration']) - print(duration) overnightCost = tmp.at[0, 'Decommissioning_OvernightCost'] cashFlowShape = capital_shape( duration - duration // 2, duration // 2) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index f37e18c4..549cda07 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -12,7 +12,7 @@ eco_props_agents = ["capital", "operation_maintenance", - "decomission", + "decommission", "fuels"] eco_props_region = ["finance"] + eco_props_agents eco_properties = ["periode"] + eco_props_region @@ -32,20 +32,6 @@ def load_economic_info(self, eco_input): data = yaml.load(stream, Loader=yaml.FullLoader) self.dict = data - def get_filiation(self, name, dfEntry): - filiation = [] - filiation.append(name) - parent_id = dfEntry[dfEntry["Prototype"] == name]["ParentId"][0] - - while parent_id != -1: - # get the parent - parent_entry = dfEntry[dfEntry["AgentId"] == parent_id] - parent_name = parent_entry.iloc[0]["Prototype"] - filiation.append(parent_name) - # get the parent of the parent - parent_id = parent_entry.iloc[0]["ParentId"] - return list(reversed(filiation)) - def update_prop(self, proto, traveling_dict, key, properties, prop_list): updated = False if key in traveling_dict: @@ -58,7 +44,7 @@ def update_prop(self, proto, traveling_dict, key, properties, prop_list): properties[prop] = traveling_dict[prop] return updated, traveling_dict - def get_prototype_eco(self, name, filiation): + def get_prototype_eco(self, filiation): proto_eco = {} traveling_dict = self.dict["eco_model"] for prop in eco_properties: @@ -86,350 +72,24 @@ def get_prototype_eco(self, name, filiation): return proto_eco -def load_economic_info(eco_input): - tuples = ['Prototype', - 'AgentId', - 'ReturnOnDebt', - 'ReturnOnEquity', - 'TaxRate', - 'DiscountRate', - 'beforePeak', - 'afterPeak', - 'constructionDuration', - 'Captial_Deviation', - 'OvernightCost', - 'Duration', - 'OvernightCost', - 'FixedCost', - 'VariableCost', - 'OperationMaintenance_Deviation', - 'Commodity', - 'SupplyCost', - 'WasteFee', - 'Fuel_Deviation', - 'Begin', - 'End'] - #rtn = pd.DataFrame(index=tuples) - #agentIndex = dfEntry.reset_index().set_index('AgentId')['index'] - #rtn = rtn.T - #rtn['Agent_Prototype'] = dfEntry['Prototype'] - #rtn['Agent_AgentId'] = dfEntry['AgentId'] - #rtn['Agent_ParentId'] = dfEntry['ParentId'] - #parametersInput = 'tests/parameters.xml' - #for child in root: - # print(child.tag, child.attrib) - # - #def add_finance(rtn, root): - - - #def add_capital(rtn, root): - #def add_decommisioning(rtn, root): - - #def add_operation_maintenance(rtn, root): - - #def add_fuel(rtn, root): - # - #add_finance(rtn, root) - - - # for region in root.findall('region'): - # idRegion = int(region.find('id').text) - # finance = region.find('finance') - # if finance is not None: - # returnOnDebt = float(finance.find('return_on_debt').text) - # returnOnEquity = float(finance.find('return_on_equity').text) - # taxRate = float(finance.find('tax_rate').text) - # discountRate = float(finance.find('discount_rate').text) - # rtn.loc[agentIndex[idRegion], 'Finance_TaxRate'] = taxRate - # rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnDebt'] = returnOnDebt - # rtn.loc[agentIndex[idRegion], 'Finance_ReturnOnEquity'] = returnOnEquity - # rtn.loc[gent_index[idRegion], 'Finance_DiscountRate'] = discountRate - # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - # rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate - # rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt - # rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnEquity'] = returnOnEquity - # rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate - # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt - # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity - # rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate - # capital = region.find('capital') - # if capital is not None: - # beforePeak = int(capital.find('beforePeak').text) - # afterPeak = int(capital.find('afterPeak').text) - # constructionDuration = int(capital.find('constructionDuration').text) - # deviation = float(capital.find('deviation').text) - # overnightCost = float(capital.find('overnight_cost').text) - # rtn.loc[agentIndex[idRegion], 'Captial_beforePeak'] = beforePeak - # rtn.loc[agentIndex[idRegion], 'Captial_afterPeak'] = afterPeak - # rtn.loc[agentIndex[idRegion], 'Captial_constructionDuration'] = constructionDuration - # rtn.loc[agentIndex[idRegion], 'Captial_Deviation'] = deviation - # rtn.loc[agentIndex[idRegion], 'Captial_OvernightCost'] = overnightCost - # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - # rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak - # rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak - # rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration - # rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation - # rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - # rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak - # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost - # decommissioning = region.find('decommissioning') - # if decommissioning is not None: - # duration = int(decommissioning.find('duration').text) - # overnightCost = float(decommissioning.find('overnight_cost').text) - # rtn.loc[agentIndex[idRegion], 'Decommissioning_Duration'] = duration - # rtn.loc[agentIndex[idRegion], 'Decommissioning_OvernightCost'] = overnightCost - # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - # rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration - # rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost - # operation_maintenance = region.find('operation_maintenance') - # if operation_maintenance is not None: - # fixed = float(operation_maintenance.find('fixed').text) - # variable = float(operation_maintenance.find('variable').text) - # deviation = float(operation_maintenance.find('deviation').text) - # rtn.loc[agentIndex[idRegion], 'OperationMaintenance_FixedCost'] = fixed - # rtn.loc[agentIndex[idRegion], 'OperationMaintenance_VariableCost'] = variable - # rtn.loc[agentIndex[idRegion], 'OperationMaintenance_Deviation'] = deviation - # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed - # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable - # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - # fuel = region.find('fuel') - # if fuel is not None: - # for type in fuel.findall('type'): - # supply = float(type.find('supply_cost').text) - # waste = float(type.find('waste_fee').text) - # name = type.find('name').text - # deviation = float(type.find('deviation').text) - # if np.isnan(rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idRegion], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idRegion], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idRegion], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idRegion], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idRegion]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # for idInstitution in dfEntry[dfEntry.ParentId==idRegion]['AgentId'].tolist(): - # if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # for institution in region.findall('institution'): - # idInstitution = int(institution.find('id').text) - # finance = institution.find('finance') - # if finance is not None: - # returnOnDebt = float(finance.find('return_on_debt').text) - # returnOnEquity = float(finance.find('return_on_equity').text) - # taxRate = float(finance.find('tax_rate').text) - # discountRate = float(finance.find('discount_rate').text) - # rtn.loc[agentIndex[idInstitution], 'Finance_TaxRate'] = taxRate - # rtn.loc[agentIndex[idInstitution], 'Finance_ReturnOnDebt'] = returnOnDebt - # rtn.loc[agentIndex[idInstitution],'Finance_ReturnOnEquity'] = returnOnEquity - # rtn.loc[gent_index[idInstitution], 'Finance_DiscountRate'] = discountRate - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'Finance_TaxRate'] = taxRate - # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnDebt'] = returnOnDebt - # rtn.loc[agentIndex[idFacility], 'Finance_ReturnOnEquity'] = returnOnEquity - # rtn.loc[gent_index[idFacility], 'Finance_DiscountRate'] = discountRate - # capital = institution.find('capital') - # if capital is not None: - # beforePeak = int(capital.find('beforePeak').text) - # afterPeak = int(capital.find('afterPeak').text) - # constructionDuration = int(capital.find('constructionDuration').text) - # deviation = float(capital.find('deviation').text) - # overnightCost = float(capital.find('overnight_cost').text) - # rtn.loc[agentIndex[idInstitution], 'Captial_beforePeak'] = beforePeak - # rtn.loc[agentIndex[idInstitution], 'Captial_afterPeak'] = afterPeak - # rtn.loc[agentIndex[idInstitution], 'Captial_constructionDuration'] = constructionDuration - # rtn.loc[agentIndex[idInstitution], 'Captial_Deviation'] = deviation - # rtn.loc[agentIndex[idInstitution], 'Captial_OvernightCost'] = overnightCost - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnightCost - # decommissioning = institution.find('decommissioning') - # if decommissioning is not None: - # duration = int(decommissioning.find('duration').text) - # overnightCost = float(decommissioning.find('overnight_cost').text) - # rtn.loc[agentIndex[idInstitution], 'Decommissioning_Duration'] = duration - # rtn.loc[agentIndex[idInstitution], 'Decommissioning_OvernightCost'] = overnightCost - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnightCost - # operation_maintenance = institution.find('operation_maintenance') - # if operation_maintenance is not None: - # fixed = float(operation_maintenance.find('fixed').text) - # variable = float(operation_maintenance.find('variable').text) - # deviation = float(operation_maintenance.find('deviation').text) - # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_FixedCost'] = fixed - # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_VariableCost'] = variable - # rtn.loc[agentIndex[idInstitution], 'OperationMaintenance_Deviation'] = deviation - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - # fuel = institution.find('fuel') - # if fuel is not None: - # for type in fuel.findall('type'): - # supply = float(type.find('supply_cost').text) - # waste = float(type.find('waste_fee').text) - # name = type.find('name').text - # deviation = float(type.find('deviation').text) - # if np.isnan(rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idInstitution], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idInstitution], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idInstitution], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idInstitution], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idInstitution]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # for idFacility in dfEntry[dfEntry.ParentId==idInstitution]['AgentId'].tolist(): - # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # for prototype in institution.findall('prototype'): - # name = prototype.find('name').text - # tmp = dfEntry[dfEntry.ParentId==idInstitution] - # facilityIdList = tmp[tmp.Prototype==name].loc[:,'AgentId'].tolist() - # capital = prototype.find('capital') - # if capital is not None: - # beforePeak = int(capital.find('beforePeak').text) - # afterPeak = int(capital.find('afterPeak').text) - # constructionDuration = int(capital.find('constructionDuration').text) - # deviation = float(capital.find('deviation').text) - # overnight = float(capital.find('overnight_cost').text) - # for idFacility in facilityIdList: - # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = beforePeak - # rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = afterPeak - # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = constructionDuration - # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = deviation - # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = overnight - # operation_maintenance = prototype.find('operation_maintenance') - # if operation_maintenance is not None: - # fixed = float(operation_maintenance.find('fixed').text) - # variable = float(operation_maintenance.find('variable').text) - # deviation = float(operation_maintenance.find('deviation').text) - # for idFacility in facilityIdList: - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = fixed - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = variable - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = deviation - # fuel = prototype.find('fuel') - # if fuel is not None: - # for type in fuel.findall('type'): - # supply = float(type.find('supply_cost').text) - # waste = float(type.find('waste_fee').text) - # name = type.find('name').text - # deviation = float(type.find('deviation').text) - # for idFacility in facilityIdList: - # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # decommissioning = prototype.find('decommissioning') - # if decommissioning is not None: - # duration = int(decommissioning.find('duration').text) - # overnight = float(decommissioning.find('overnight_cost').text) - # for idFacility in facilityIdList: - # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = duration - # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = overnight - # for facility in prototype.findall('facility'): - # idFacility = int(facility.find('id').text) - # capital = facility.find('capital') - # if capital is not None: - # rtn.loc[agentIndex[idFacility], 'Captial_beforePeak'] = int(capital.find('beforePeak').text) - # rtn.loc[agentIndex[idFacility], 'Captial_afterPeak'] = int(capital.find('afterPeak').text) - # rtn.loc[agentIndex[idFacility], 'Captial_constructionDuration'] = int(capital.find('constructionDuration').text) - # rtn.loc[agentIndex[idFacility], 'Captial_Deviation'] = float(capital.find('deviation').text) - # rtn.loc[agentIndex[idFacility], 'Captial_OvernightCost'] = float(capital.find('overnight_cost').text) - # operation_maintenance = facility.find('operation_maintenance') - # if operation_maintenance is not None: - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_FixedCost'] = float(operation_maintenance.find('fixed').text) - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_VariableCost'] = float(operation_maintenance.find('variable').text) - # rtn.loc[agentIndex[idFacility], 'OperationMaintenance_Deviation'] = float(operation_maintenance.find('deviation').text) - # fuel = facility.find('fuel') - # if fuel is not None: - # for type in fuel.findall('type'): - # supply = float(type.find('supply_cost').text) - # waste = float(type.find('waste_fee').text) - # name = type.find('name').text - # deviation = float(type.find('deviation').text) - # if np.isnan(rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost']): - # rtn.loc[agentIndex[idFacility], 'Fuel_Commodity'] = name - # rtn.loc[agentIndex[idFacility], 'Fuel_SupplyCost'] = supply - # rtn.loc[agentIndex[idFacility], 'Fuel_WasteFee'] = waste - # rtn.loc[agentIndex[idFacility], 'Fuel_Deviation'] = deviation - # else: - # indice = rtn.index.size - # rtn.loc[indice] = rtn.loc[agentIndex[idFacility]] - # rtn.loc[indice, 'Fuel_Commodity'] = name - # rtn.loc[indice, 'Fuel_SupplyCost'] = supply - # rtn.loc[indice, 'Fuel_WasteFee'] = waste - # rtn.loc[indice, 'Fuel_Deviation'] = deviation - # decommissioning = facility.find('decommissioning') - # if decommissioning is not None: - # rtn.loc[agentIndex[idFacility], 'Decommissioning_Duration'] = int(decommissioning.find('duration').text) - # rtn.loc[agentIndex[idFacility], 'Decommissioning_OvernightCost'] = float(decommissioning.find('overnight_cost').text) - #return rtn +def get_filiation_per_name(name, dfEntry): + filiation = [] + filiation.append(name) + parent_id = dfEntry[dfEntry["Prototype"] == name]["ParentId"][0] + + while parent_id != -1: + # get the parent + parent_entry = dfEntry[dfEntry["AgentId"] == parent_id] + parent_name = parent_entry.iloc[0]["Prototype"] + filiation.append(parent_name) + # get the parent of the parent + parent_id = parent_entry.iloc[0]["ParentId"] + return list(reversed(filiation)) + +def get_filiation_per_id(id, dfEntry): + name = dfEntry[dfEntry["AgentId"] == id]["Prototype"][0] + return get_filiation_per_name(name, dfEntry) #################### # Mining & Milling # diff --git a/tests/parameters.yml b/tests/parameters.yml index 15548e9f..c346d0eb 100644 --- a/tests/parameters.yml +++ b/tests/parameters.yml @@ -68,10 +68,10 @@ eco_model: - prototype: MyInst capital: - deviation: 0 beforePeak: 10 - afterPeak: 75 + afterPeak: 5 constructionDuration: 10 + deviation: 0 overnight_cost: 1 fuels: diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index e998d83a..8ce9fdc9 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -37,27 +37,20 @@ def test_capital_cost(): ('Time', ' Date: Tue, 26 May 2020 10:51:48 -0500 Subject: [PATCH 37/64] inbetween --- cymetric/eco_metrics.py | 3 +++ cymetric/eco_tools.py | 35 +++++++++++++++++++++++++++++++++++ tests/test_eco_metrics.py | 1 + 3 files changed, 39 insertions(+) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 56913be0..4031d39e 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -127,6 +127,9 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): # Unsure if it is about Sender or Receiver implementation here and test are not # in agreement, taking receiver (using implementation as ref) rtn = dfTransactions.rename(columns={'ReceiverId': 'AgentId'}) + + agents_eco_prop = eco_data.get_prototypes_eco() + # add quantity to Transaction base_col = ['SimId', 'ResourceId'] diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 549cda07..b8fdee22 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -17,6 +17,13 @@ eco_props_region = ["finance"] + eco_props_agents eco_properties = ["periode"] + eco_props_region +finance_col = ["discount_rate", "tax_rate", "return_on_debt", + "return_on_equity"] +capital_col = ["beforePeak", "afterPeak", "constructionDuration", + "overnight_cost", "capital_dev"] +operation_col = ["fixed", "variable", "operation_dev"] +fuel_col = ["name", "supply_cost", "waste_fee", "fuel_dev"] + class eco_input_data(): """The EconomicInfo metric stores all economic data needed to calculate the @@ -71,6 +78,32 @@ def get_prototype_eco(self, filiation): return proto_eco + def get_prototypes_eco(self): + proto_eco = {} + model_dict = self.dict["eco_model"] + + for prop in eco_properties: + if prop in model_dict: + proto_eco[prop] = model_dict[prop] + + for region_dict in model_dict["region"]: + region_eco = proto_eco + region_eco["prototype"] = region_dict["prototype"] + for prop in eco_properties: + if prop in region_dict: + proto_eco[prop] = region_dict[prop] + print(region_eco) + region_raw = pd.DataFrame.from_dict(region_eco) + print(region_raw) + + return proto_eco + + +def build_eco_row(proto_dict): + row_col = finance_col + capital_col + operation_col + fuel_col + df = df.DataFrame(columns=row_col) + + def get_filiation_per_name(name, dfEntry): filiation = [] @@ -91,10 +124,12 @@ def get_filiation_per_id(id, dfEntry): name = dfEntry[dfEntry["AgentId"] == id]["Prototype"][0] return get_filiation_per_name(name, dfEntry) + #################### # Mining & Milling # #################### + def isuraniumsource(dfEntry, id): """ Input : Agents entry table and agent id diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 8ce9fdc9..9bd1a6c5 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -131,6 +131,7 @@ def test_fuel_cost(): ('Fuel_WasteFee', ' Date: Tue, 26 May 2020 14:11:15 -0500 Subject: [PATCH 38/64] temp commit --- cymetric/eco_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 4031d39e..25a266fb 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -127,7 +127,7 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): # Unsure if it is about Sender or Receiver implementation here and test are not # in agreement, taking receiver (using implementation as ref) rtn = dfTransactions.rename(columns={'ReceiverId': 'AgentId'}) - + agents_eco_prop = eco_data.get_prototypes_eco() From 9af8620bd6a72f1493b57eb2f2d526b1e9b4575a Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Tue, 26 May 2020 15:05:38 -0500 Subject: [PATCH 39/64] temp commit --- cymetric/eco_tools.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index b8fdee22..908ff0da 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -93,7 +93,7 @@ def get_prototypes_eco(self): if prop in region_dict: proto_eco[prop] = region_dict[prop] print(region_eco) - region_raw = pd.DataFrame.from_dict(region_eco) + region_raw = build_eco_row(region_eco) print(region_raw) return proto_eco @@ -101,7 +101,31 @@ def get_prototypes_eco(self): def build_eco_row(proto_dict): row_col = finance_col + capital_col + operation_col + fuel_col - df = df.DataFrame(columns=row_col) + df = pd.DataFrame(columns=row_col) + for fuel_type in proto_dict["fuels"]: + print(fuel_type) + print(proto_dict["finance"]["discount_rate"]) + a_row = pd.Series([ + float(proto_dict["finance"]["discount_rate"]), + float(proto_dict["finance"]["tax_rate"]), + float(proto_dict["finance"]["return_on_debt"]), + float(proto_dict["finance"]["return_on_equity"]), + float(proto_dict["capital"]["beforePeak"]), + float(proto_dict["capital"]["afterPeak"]), + float(proto_dict["capital"]["constructionDuration"]), + float(proto_dict["capital"]["overnight_cost"]), + float(proto_dict["capital"]["deviation"]), + float(proto_dict["operation_maintenance"]["fixed"]), + float(proto_dict["operation_maintenance"]["variable"]), + float(proto_dict["operation_maintenance"]["deviation"]), + fuel_type["name"], + float(fuel_type["supply_cost"]), + float(fuel_type["waste_fee"]), + float(fuel_type["deviation"]) + ]) + row_df = pd.DataFrame([a_row], columns=row_col) + df = pd.concat([row_df, df], ignore_index=True) + return df From 4164ef355a3c9fd8f0f88c35098600feb889f9c0 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Tue, 26 May 2020 16:40:54 -0500 Subject: [PATCH 40/64] almost building a df with facility properties --- cymetric/eco_tools.py | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 908ff0da..7fe1b7f6 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -9,6 +9,7 @@ import numpy as np import yaml import math +from cymetric.tools import ensure_dt_bytes eco_props_agents = ["capital", "operation_maintenance", @@ -98,14 +99,21 @@ def get_prototypes_eco(self): return proto_eco +finance_col = ["discount_rate", "tax_rate", "return_on_debt", + "return_on_equity"] +capital_col = ["beforePeak", "afterPeak", "constructionDuration", + "overnight_cost", "capital_dev"] +operation_col = ["fixed", "variable", "operation_dev"] +fuel_col = ["name", "supply_cost", "waste_fee", "fuel_dev"] def build_eco_row(proto_dict): row_col = finance_col + capital_col + operation_col + fuel_col + print(row_col) df = pd.DataFrame(columns=row_col) + + for fuel_type in proto_dict["fuels"]: - print(fuel_type) - print(proto_dict["finance"]["discount_rate"]) - a_row = pd.Series([ + a_row = pd.DataFrame(np.array([( float(proto_dict["finance"]["discount_rate"]), float(proto_dict["finance"]["tax_rate"]), float(proto_dict["finance"]["return_on_debt"]), @@ -121,14 +129,31 @@ def build_eco_row(proto_dict): fuel_type["name"], float(fuel_type["supply_cost"]), float(fuel_type["waste_fee"]), - float(fuel_type["deviation"]) - ]) - row_df = pd.DataFrame([a_row], columns=row_col) - df = pd.concat([row_df, df], ignore_index=True) + float(fuel_type["deviation"])) + ], + dtype=ensure_dt_bytes([ + ('discount_rate', ' Date: Wed, 27 May 2020 10:39:44 -0500 Subject: [PATCH 41/64] formating --- cymetric/eco_tools.py | 73 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 7fe1b7f6..5808b561 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -99,6 +99,7 @@ def get_prototypes_eco(self): return proto_eco + finance_col = ["discount_rate", "tax_rate", "return_on_debt", "return_on_equity"] capital_col = ["beforePeak", "afterPeak", "constructionDuration", @@ -106,49 +107,49 @@ def get_prototypes_eco(self): operation_col = ["fixed", "variable", "operation_dev"] fuel_col = ["name", "supply_cost", "waste_fee", "fuel_dev"] + def build_eco_row(proto_dict): row_col = finance_col + capital_col + operation_col + fuel_col print(row_col) df = pd.DataFrame(columns=row_col) - for fuel_type in proto_dict["fuels"]: a_row = pd.DataFrame(np.array([( - float(proto_dict["finance"]["discount_rate"]), - float(proto_dict["finance"]["tax_rate"]), - float(proto_dict["finance"]["return_on_debt"]), - float(proto_dict["finance"]["return_on_equity"]), - float(proto_dict["capital"]["beforePeak"]), - float(proto_dict["capital"]["afterPeak"]), - float(proto_dict["capital"]["constructionDuration"]), - float(proto_dict["capital"]["overnight_cost"]), - float(proto_dict["capital"]["deviation"]), - float(proto_dict["operation_maintenance"]["fixed"]), - float(proto_dict["operation_maintenance"]["variable"]), - float(proto_dict["operation_maintenance"]["deviation"]), - fuel_type["name"], - float(fuel_type["supply_cost"]), - float(fuel_type["waste_fee"]), - float(fuel_type["deviation"])) - ], - dtype=ensure_dt_bytes([ - ('discount_rate', ' Date: Wed, 27 May 2020 10:40:29 -0500 Subject: [PATCH 42/64] add vsvode to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4df38132..c2ade00d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ cymetric/typesystem.pyx # Rever rever/ +.vscode From 3c2a8b3c500e05c81fbfa59e21213d38958f1bf2 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Wed, 27 May 2020 10:54:36 -0500 Subject: [PATCH 43/64] some addition formating --- cymetric/eco_tools.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 5808b561..a9d8d3b4 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -5,10 +5,10 @@ metrics calculations. All prices are 2015 $ """ +import math +import yaml import pandas as pd import numpy as np -import yaml -import math from cymetric.tools import ensure_dt_bytes eco_props_agents = ["capital", @@ -61,21 +61,21 @@ def get_prototype_eco(self, filiation): for proto in filiation: updated = False - status, traveling_dict = self.update_prop(proto, traveling_dict, - "region", proto_eco, - eco_props_region) + updated, traveling_dict = self.update_prop(proto, traveling_dict, + "region", proto_eco, + eco_props_region) if not updated: - status, traveling_dict = self.update_prop(proto, - traveling_dict, - "institution", - proto_eco, - eco_props_agents) + updated, traveling_dict = self.update_prop(proto, + traveling_dict, + "institution", + proto_eco, + eco_props_agents) if not updated: - status, traveling_dict = self.update_prop(proto, - traveling_dict, - "facility", - proto_eco, - eco_props_agents) + updated, traveling_dict = self.update_prop(proto, + traveling_dict, + "facility", + proto_eco, + eco_props_agents) return proto_eco @@ -212,6 +212,7 @@ def swu(feedMass, feedAssay, productMass, productAssay, wasteMass, wasteAssay): """ rtn_value = wasteMass * V(wasteAssay) + productMass * V(productAssay) \ - feedMass * V(feedAssay) + return rtn_value def waste_mass(feedMass, productMass): From bf308201f00d1fbe87eaccd53423e1871bc72d9e Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Wed, 27 May 2020 15:58:19 -0500 Subject: [PATCH 44/64] Capital cost working with the new layout --- cymetric/eco_metrics.py | 544 ++++++++++++++++++++++++++++------------ cymetric/eco_tools.py | 71 +++--- 2 files changed, 422 insertions(+), 193 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 25a266fb..597a1458 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -89,14 +89,14 @@ def capital_cost(dfPower, dfEntry, dfInfo): 1) / (discountRate * math.ceil((beforePeak + afterPeak) / 12)) entry_time = dfEntry[ - dfEntry['AgentId'] == agent_id].iloc[0]["EnterTime"] + dfEntry['AgentId'] == agent_id].iloc[0]["EnterTime"] TimeSerie = list(range(beforePeak + afterPeak + 1)) TimeSerie += entry_time - constructionDuration tmp = pd.DataFrame(data={'AgentId': agent_id, 'Time': TimeSerie, 'Payment': cashFlow}, columns=['AgentId', 'Time', 'Payment']) - rtn = pd.concat([rtn, tmp], ignore_index=False) + rtn = pd.concat([rtn, tmp], ignore_index=False, sort=False) rtn['SimId'] = dfPower['SimId'].iloc[0] rtn = rtn[rtn['Time'].apply(lambda x: x >= 0 and x < simDuration)] @@ -130,7 +130,6 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): agents_eco_prop = eco_data.get_prototypes_eco() - # add quantity to Transaction base_col = ['SimId', 'ResourceId'] added_col = base_col + ['Quantity'] @@ -233,7 +232,7 @@ def operation_maintenance(dfPower, dfEcoInfo): rtn = pd.merge(dfPower[added_col], rtn, on=base_col) rtn['Value'] *= 8760 / 12 rtn['Payment'] = (rtn['Value'] * rtn['VariableCost'] + - max(rtn['Value'])*rtn['FixedCost']) + max(rtn['Value']) * rtn['FixedCost']) return rtn[['SimId', 'AgentId', 'Time', 'Payment']] @@ -268,8 +267,6 @@ def operation_maintenance(dfPower, dfEcoInfo): ('Truncation_End', ts.INT)] - - """The functions below aim at calculating more complex metrics than the simple cash flows corresponding to the construction, fuel, O&M and decommissioning costs. The metrics can be calculated at an agent, institution, region or simulation level. """ ####################################### @@ -285,30 +282,32 @@ def annual_costs(outputDb, reactorId, capital=True): """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) - + dfInfo = evaler.eval('Info') duration = dfInfo['Duration'].iloc[0] initialYear = dfInfo['InitialYear'].iloc[0] initialMonth = dfInfo['InitialMonth'].iloc[0] - + dfEntry = evaler.eval('AgentEntry') print(dfEntry) - commissioning = dfEntry[dfEntry.AgentId==reactorId]['EnterTime'].iloc[0] + commissioning = dfEntry[dfEntry.AgentId == reactorId]['EnterTime'].iloc[0] dfCapitalCosts = evaler.eval('CapitalCost') print(dfCapitalCosts) - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts.AgentId==reactorId].copy() + dfCapitalCosts = dfCapitalCosts[dfCapitalCosts.AgentId == reactorId].copy() dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame({'Capital' : dfCapitalCosts['Payment']}, index=list(range(duration))) + costs = pd.DataFrame( + {'Capital': dfCapitalCosts['Payment']}, index=list(range(duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts.AgentId==reactorId].copy() + dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts.AgentId == reactorId].copy( + ) dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance') - dfOMCosts = dfOMCosts[dfOMCosts.AgentId==reactorId].copy() + dfOMCosts = dfOMCosts[dfOMCosts.AgentId == reactorId].copy() dfOMCosts = dfOMCosts.groupby('Time').sum() costs['OandM'] = dfOMCosts['Payment'] dfFuelCosts = evaler.eval('FuelCost') - dfFuelCosts = dfFuelCosts[dfFuelCosts.AgentId==reactorId].copy() + dfFuelCosts = dfFuelCosts[dfFuelCosts.AgentId == reactorId].copy() dfFuelCosts = dfFuelCosts.groupby('Time').sum() costs['Fuel'] = dfFuelCosts['Payment'] costs = costs.fillna(0) @@ -318,13 +317,15 @@ def annual_costs(outputDb, reactorId, capital=True): costs = costs.groupby('Year').sum() return costs + def annual_costs_present_value(outputDb, reactorId, capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ costs = annual_costs(outputDb, reactorId, capital) actualization = actualization_vector(len(costs)) actualization.index = costs.index - return costs.apply(lambda x : x * actualization) + return costs.apply(lambda x: x * actualization) + def average_cost(outputDb, reactorId, capital=True): """Input : sqlite output database, reactor's AgentId @@ -333,15 +334,19 @@ def average_cost(outputDb, reactorId, capital=True): db = dbopen(outputDb) evaler = Evaluator(db, write=False) dfPower = evaler.eval('TimeSeriesPower').reset_index() - powerGenerated = sum(dfPower[dfPower.AgentId==reactorId].loc[:, 'Value']) * 8760 / 12 - return annual_costs(outputDb, reactorId, capital).sum().sum() / powerGenerated + powerGenerated = sum( + dfPower[dfPower.AgentId == reactorId].loc[:, 'Value']) * 8760 / 12 + return annual_costs(outputDb, reactorId, + capital).sum().sum() / powerGenerated + def benefit(outputDb, reactorId): """Input : sqlite output database and reactor agent id Output : cumulative sum of actualized income and expense (= - expenditures + income) """ costs = - annual_costs(outputDb, reactorId).sum(axis=1) - powerGenerated = power_generated(outputDb, reactorId) * lcoe(outputDb, reactorId) + powerGenerated = power_generated( + outputDb, reactorId) * lcoe(outputDb, reactorId) rtn = pd.concat([costs, powerGenerated], axis=1).fillna(0) rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() actualization = actualization_vector(len(rtn)) @@ -349,6 +354,7 @@ def benefit(outputDb, reactorId): rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn + def lcoe(outputDb, reactorId, capital=True): """Input : sqlite output database and reactor agent id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) @@ -362,7 +368,9 @@ def lcoe(outputDb, reactorId, capital=True): powerGenerated = power_generated(outputDb, reactorId) actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ + ((powerGenerated * actualization).fillna(0).sum()) + def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): """Input : sqlite output database, reactor id, time window (t0, period) @@ -380,28 +388,40 @@ def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): costs = annual_costs(outputDb, reactorId, capital) costs = costs.sum(axis=1) power = power_generated(outputDb, reactorId) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df = pd.DataFrame(index=list( + range(initialYear, initialYear + duration // 12 + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear # year instead of months + simulationBegin = (simulationBegin + initialMonth - + 1) // 12 + initialYear # year instead of months simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) rtn['Power'] = pd.Series() rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ + (1 + default_discount_rate) - \ + df.loc[j - 1 + t0, 'Power'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Power'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** ( + 1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) actualization = actualization_vector(len(rtn)) actualization.index = rtn.index rtn['Actualized'] = rtn['Ratio'] * actualization return rtn + def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): """Just for tests : another way to calculate the period costs """ @@ -414,7 +434,14 @@ def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): costs = annual_costs(outputDb, institutionId, capital) costs = costs.sum(axis=1) power = power_generated(outputDb, institutionId) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -429,12 +456,15 @@ def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): rtn = rtn.fillna(0) for j in range(simulationBegin, simulationEnd + 1): for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - j) #tmp['WasteManagement'][j] = pd.Series() - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn + def power_generated(outputDb, reactorId): """Input : sqlite output database and reactor agent id Output : Electricity generated in MWh every year @@ -446,15 +476,19 @@ def power_generated(outputDb, reactorId): duration = dfInfo.loc[0, 'Duration'] initialYear = dfInfo.loc[0, 'InitialYear'] initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfPower = dfPower[dfPower['AgentId']==reactorId].copy() + dfPower = dfPower[dfPower['AgentId'] == reactorId].copy() dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, initialYear + (initialMonth + duration) // 12 + 1))) + rtn = pd.Series(dfPower['Value'] * 8760 / 12, + index=list(range(initialYear, + initialYear + (initialMonth + duration) // 12 + 1))) return rtn.fillna(0) # Institution level -def institution_annual_costs(outputDb, institutionId, capital=True, truncate=True): + +def institution_annual_costs( + outputDb, institutionId, capital=True, truncate=True): """Input : sqlite output database and institution's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. Output : total reactor costs per year over its lifetime at the institution level. """ @@ -468,53 +502,64 @@ def institution_annual_costs(outputDb, institutionId, capital=True, truncate=Tru simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId==institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] dfPower = evaler.eval('TimeSeriesPower') - reactorIds = dfEntry[dfEntry['AgentId'].apply(lambda x: isreactor(dfPower, x))]['AgentId'].tolist() + reactorIds = dfEntry[dfEntry['AgentId'].apply( + lambda x: isreactor(dfPower, x))]['AgentId'].tolist() dfCapitalCosts = evaler.eval('CapitalCost').reset_index() - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame({'Capital' : dfCapitalCosts['Payment']}, index=list(range(0, duration))) + costs = pd.DataFrame( + {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance').reset_index() - dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfOMCosts = dfOMCosts.groupby('Time').sum() costs['OandM'] = dfOMCosts.loc[:, 'Payment'] dfFuelCosts = evaler.eval('FuelCost').reset_index() - dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfFuelCosts = dfFuelCosts.groupby('Time').sum() costs['Fuel'] = dfFuelCosts.loc[:, 'Payment'] costs = costs.fillna(0) costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear if truncate: endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x : x <= endYear)] + costs = costs[costs['Year'].apply(lambda x: x <= endYear)] beginYear = (simulationBegin + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x : x >= beginYear)] + costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] if not capital: del costs['Capital'] costs = costs.groupby('Year').sum() return costs + def institution_annual_costs_present_value(outputDb, reactorId, capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ costs = institution_annual_costs(outputDb, institutionId, capital) actualization = actualization_vector(len(costs)) actualization.index = costs.index - return costs.apply(lambda x : x * actualization) + return costs.apply(lambda x: x * actualization) + def institution_benefit(outputDb, institutionId): """Input : sqlite output database and institution agent id Output : cumulative sum of income and expense (= - expenditures + income) """ costs = - institution_annual_costs(outputDb, institutionId).sum(axis=1) - power_gen = institution_power_generated(outputDb, institutionId) * institution_average_lcoe(outputDb, institutionId)['Average LCOE'] + power_gen = institution_power_generated( + outputDb, institutionId) * institution_average_lcoe( + outputDb, institutionId)['Average LCOE'] rtn = pd.concat([costs, power_gen], axis=1).fillna(0) rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() actualization = actualization_vector(len(rtn)) @@ -522,7 +567,9 @@ def institution_benefit(outputDb, institutionId): rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn -def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=True): + +def institution_period_costs( + outputDb, institutionId, t0=0, period=20, capital=True): """Input : sqlite output database, institution id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ @@ -535,10 +582,19 @@ def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=T dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] - costs = institution_annual_costs(outputDb, institutionId, capital, truncate=False) + costs = institution_annual_costs( + outputDb, institutionId, capital, truncate=False) costs = costs.sum(axis=1) - power = institution_power_generated(outputDb, institutionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + power = institution_power_generated( + outputDb, institutionId, truncate=False) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -549,18 +605,30 @@ def institution_period_costs(outputDb, institutionId, t0=0, period=20, capital=T rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, + 'Power'] = rtn.loc[j - 1, + 'Power'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, + 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, + 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, + 'Payment'] = rtn.loc[j - 1, + 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, + 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, + 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) actualization = actualization_vector(len(rtn)) actualization.index = rtn.index rtn['Actualized'] = rtn['Ratio'] * actualization return rtn -def institution_period_costs2(outputDb, institutionId, t0=0, period=20, capital=True): + +def institution_period_costs2( + outputDb, institutionId, t0=0, period=20, capital=True): """Just for tests : another method for period costs """ db = dbopen(outputDb) @@ -572,10 +640,19 @@ def institution_period_costs2(outputDb, institutionId, t0=0, period=20, capital= dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] - costs = institution_annual_costs(outputDb, institutionId, capital, truncate=False) + costs = institution_annual_costs( + outputDb, institutionId, capital, truncate=False) costs = costs.sum(axis=1) - power = institution_power_generated(outputDb, institutionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + power = institution_power_generated( + outputDb, institutionId, truncate=False) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -587,11 +664,14 @@ def institution_period_costs2(outputDb, institutionId, t0=0, period=20, capital= rtn = rtn.fillna(0) for j in range(simulationBegin, simulationEnd + 1): for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - j) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn + def institution_power_generated(outputDb, institutionId, truncate=True): """Input : sqlite output database and institution agent id Output : Sum of electricity generated in MWh every year in the institution reactor fleet @@ -606,18 +686,23 @@ def institution_power_generated(outputDb, institutionId, truncate=True): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId==institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] dfPower = evaler.eval('TimeSeriesPower') - reactorIds = dfEntry[dfEntry['AgentId'].apply(lambda x: isreactor(dfPower, x))]['AgentId'].tolist() + reactorIds = dfEntry[dfEntry['AgentId'].apply( + lambda x: isreactor(dfPower, x))]['AgentId'].tolist() dfPower = evaler.eval('TimeSeriesPower').reset_index() dfPower = dfPower[dfPower['AgentId'].apply(lambda x: x in reactorIds)] dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, initialYear + (initialMonth + duration) // 12 + 1))) + rtn = pd.Series(dfPower['Value'] * 8760 / 12, + index=list(range(initialYear, + initialYear + (initialMonth + duration) // 12 + 1))) rtn.name = 'Power in MWh' return rtn.fillna(0) + def institution_lcoe(outputDb, institutionId): """Input : sqlite output database and institution agent id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) @@ -631,7 +716,8 @@ def institution_lcoe(outputDb, institutionId): powerGenerated = institution_power_generated(outputDb, institutionId) actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ + ((powerGenerated * actualization).fillna(0).sum()) def institution_average_lcoe(outputDb, institutionId): @@ -648,10 +734,12 @@ def institution_average_lcoe(outputDb, institutionId): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId==institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] dfPower = evaler.eval('TimeSeriesPower') - reactorIds = dfEntry[dfEntry['AgentId'].apply(lambda x: isreactor(dfPower, x))]['AgentId'].tolist() + reactorIds = dfEntry[dfEntry['AgentId'].apply( + lambda x: isreactor(dfPower, x))]['AgentId'].tolist() simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear dfPower = evaler.eval('TimeSeriesPower') @@ -662,20 +750,33 @@ def institution_average_lcoe(outputDb, institutionId): rtn['Temp2'] = pd.Series() for id in reactorIds: tmp = lcoe(outputDb, id) - commissioning = dfEntry[dfEntry.AgentId==id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId==id]['Lifetime'].iloc[0] - decommissioning = (commissioning + lifetime + initialMonth - 1) // 12 + initialYear + commissioning = dfEntry[dfEntry.AgentId == id]['EnterTime'].iloc[0] + lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'].iloc[0] + decommissioning = (commissioning + lifetime + + initialMonth - 1) // 12 + initialYear commissioning = (commissioning + initialMonth - 1) // 12 + initialYear - power = dfPower[dfPower.AgentId==id]['Value'].iloc[0] - rtn['Temp'] = pd.Series(tmp, index=list(range(commissioning, decommissioning + 1))) * power + power = dfPower[dfPower.AgentId == id]['Value'].iloc[0] + rtn['Temp'] = pd.Series( + tmp, + index=list( + range( + commissioning, + decommissioning + 1))) * power rtn['Weighted sum'] += rtn['Temp'].fillna(0) - rtn['Temp2'] = pd.Series(power, index=list(range(commissioning, decommissioning + 1))).fillna(0) + rtn['Temp2'] = pd.Series( + power, + index=list( + range( + commissioning, + decommissioning + + 1))).fillna(0) rtn['Power'] += rtn['Temp2'].fillna(0) rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) # Region level + def region_annual_costs(outputDb, regionId, capital=True, truncate=True): """Input : sqlite output database and region's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. Output : total reactor costs per year over its lifetime at the region level. @@ -690,56 +791,67 @@ def region_annual_costs(outputDb, regionId, capital=True, truncate=True): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - tmp = dfEntry[dfEntry.ParentId==regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] + institutionIds = tmp[tmp.Kind == 'Inst']['AgentId'].tolist() reactorIds = [] for id in institutionIds: - dfEntry2 = dfEntry[dfEntry.ParentId==id] - reactorIds += dfEntry2[dfEntry2['Spec'].apply(lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() + dfEntry2 = dfEntry[dfEntry.ParentId == id] + reactorIds += dfEntry2[dfEntry2['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() dfCapitalCosts = evaler.eval('CapitalCost').reset_index() - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame({'Capital' : dfCapitalCosts['Payment']}, index=list(range(duration))) + costs = pd.DataFrame( + {'Capital': dfCapitalCosts['Payment']}, index=list(range(duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance').reset_index() - dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfOMCosts = dfOMCosts.groupby('Time').sum() costs['OandM'] = dfOMCosts['Payment'] dfFuelCosts = evaler.eval('FuelCost').reset_index() - dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfFuelCosts = dfFuelCosts.groupby('Time').sum() costs['Fuel'] = dfFuelCosts['Payment'] costs = costs.fillna(0) costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear if truncate: endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x : x <= endYear)] + costs = costs[costs['Year'].apply(lambda x: x <= endYear)] beginYear = (simulationBegin + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x : x >= beginYear)] + costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] if not capital: del costs['Capital'] costs = costs.groupby('Year').sum() return costs -def region_annual_costs_present_value(outputDb, regionId, capital=True, truncate=True): + +def region_annual_costs_present_value( + outputDb, regionId, capital=True, truncate=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ costs = region_annual_costs(outputDb, regionId, capital) actualization = actualization_vector(len(costs)) actualization.index = costs.index - return costs.apply(lambda x : x * actualization) + return costs.apply(lambda x: x * actualization) + def region_benefit(outputDb, regionId): """Input : sqlite output database and region agent id Output : cumulative sum of actualized income and expense (= - expenditures + income) """ costs = - region_annual_costs(outputDb, regionId).sum(axis=1) - power_gen = region_power_generated(outputDb, regionId) * region_average_lcoe(outputDb, regionId)['Average LCOE'] + power_gen = region_power_generated( + outputDb, regionId) * region_average_lcoe(outputDb, regionId)['Average LCOE'] rtn = pd.concat([costs, power_gen], axis=1).fillna(0) rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() actualization = actualization_vector(len(rtn)) @@ -747,6 +859,7 @@ def region_benefit(outputDb, regionId): rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn + def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): """Input : sqlite output database, region id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] @@ -763,7 +876,14 @@ def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): costs = region_annual_costs(outputDb, regionId, capital, truncate=False) costs = costs.sum(axis=1) power = region_power_generated(outputDb, regionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -774,17 +894,28 @@ def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd + 1): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, + 'Power'] = rtn.loc[j - 1, + 'Power'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, + 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, + 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, + 'Payment'] = rtn.loc[j - 1, + 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, + 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, + 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) actualization = actualization_vector(len(rtn)) actualization.index = rtn.index rtn['Actualized'] = rtn['Ratio'] * actualization return rtn + def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): """Just for tests : another method to calculate period costs """ @@ -800,7 +931,14 @@ def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): costs = region_annual_costs(outputDb, regionId, capital, truncate=False) costs = costs.sum(axis=1) power = region_power_generated(outputDb, regionId, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -812,11 +950,14 @@ def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): rtn = rtn.fillna(0) for j in range(simulationBegin, simulationEnd + 1): for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - j) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn + def region_power_generated(outputDb, regionId, truncate=True): """Input : sqlite output database and region agent id Output : Sum of electricity generated in MWh every years in the region reactor fleet @@ -831,21 +972,26 @@ def region_power_generated(outputDb, regionId, truncate=True): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - tmp = dfEntry[dfEntry.ParentId==regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] + institutionIds = tmp[tmp.Kind == 'Inst']['AgentId'].tolist() reactorIds = [] for id in institutionIds: - dfEntry2 = dfEntry[dfEntry.ParentId==id] - reactorIds += dfEntry2[dfEntry2['Spec'].apply(lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() + dfEntry2 = dfEntry[dfEntry.ParentId == id] + reactorIds += dfEntry2[dfEntry2['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() dfPower = evaler.eval('TimeSeriesPower').reset_index() dfPower = dfPower[dfPower['AgentId'].apply(lambda x: x in reactorIds)] dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, initialYear + (initialMonth + duration) // 12 + 1))) + rtn = pd.Series(dfPower['Value'] * 8760 / 12, + index=list(range(initialYear, + initialYear + (initialMonth + duration) // 12 + 1))) rtn.name = 'Power in MWh' return rtn.fillna(0) + def region_lcoe(outputDb, regionId): """Input : sqlite output database and region agent id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) @@ -859,7 +1005,9 @@ def region_lcoe(outputDb, regionId): powerGenerated = region_power_generated(outputDb, regionId) actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ + ((powerGenerated * actualization).fillna(0).sum()) + def region_average_lcoe(outputDb, regionId): """Input : sqlite output database and region agent id @@ -875,14 +1023,16 @@ def region_average_lcoe(outputDb, regionId): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - tmp = dfEntry[dfEntry.ParentId==regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] + institutionsId = tmp[tmp.Kind == 'Inst']['AgentId'].tolist() reactorIds = [] dfPower = evaler.eval('TimeSeriesPower') for id in institutionsId: - dfEntry2 = dfEntry[dfEntry.ParentId==id] - reactorIds += dfEntry2[dfEntry2['Spec'].apply(lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() + dfEntry2 = dfEntry[dfEntry.ParentId == id] + reactorIds += dfEntry2[dfEntry2['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) @@ -892,20 +1042,33 @@ def region_average_lcoe(outputDb, regionId): rtn['Temp2'] = pd.Series() for id in reactorIds: tmp = lcoe(outputDb, id) - commissioning = dfEntry[dfEntry.AgentId==id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId==id]['Lifetime'].iloc[0] - decommissioning = (commissioning + lifetime + initialMonth - 1) // 12 + initialYear + commissioning = dfEntry[dfEntry.AgentId == id]['EnterTime'].iloc[0] + lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'].iloc[0] + decommissioning = (commissioning + lifetime + + initialMonth - 1) // 12 + initialYear commissioning = (commissioning + initialMonth - 1) // 12 + initialYear - power = dfPower[dfPower.AgentId==id]['Value'].iloc[0] - rtn['Temp'] = pd.Series(tmp, index=list(range(commissioning, decommissioning + 1))) * power + power = dfPower[dfPower.AgentId == id]['Value'].iloc[0] + rtn['Temp'] = pd.Series( + tmp, + index=list( + range( + commissioning, + decommissioning + 1))) * power rtn['Weighted sum'] += rtn['Temp'].fillna(0) - rtn['Temp2'] = pd.Series(power, index=list(range(commissioning, decommissioning + 1))).fillna(0) + rtn['Temp2'] = pd.Series( + power, + index=list( + range( + commissioning, + decommissioning + + 1))).fillna(0) rtn['Power'] += rtn['Temp2'] rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) # Simulation level + def simulation_annual_costs(outputDb, capital=True, truncate=True): """Input : sqlite output database. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. Output : total reactor costs per year over its lifetime at the simulation level. @@ -920,52 +1083,64 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] + reactorIds = dfEntry[dfEntry['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() dfCapitalCosts = evaler.eval('CapitalCost').reset_index() - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( + lambda x: x in reactorIds)] mini = min(dfCapitalCosts['Time']) dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame({'Capital' : dfCapitalCosts['Payment']}, index=list(range(0, duration))) + costs = pd.DataFrame( + {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance').reset_index() - dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfOMCosts = dfOMCosts.groupby('Time').sum() costs['OandM'] = dfOMCosts['Payment'] dfFuelCosts = evaler.eval('FuelCost').reset_index() - dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply(lambda x: x in reactorIds)] + dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( + lambda x: x in reactorIds)] dfFuelCosts = dfFuelCosts.groupby('Time').sum() costs['Fuel'] = dfFuelCosts['Payment'] costs = costs.fillna(0) costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear if truncate: endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x : x <= endYear)] + costs = costs[costs['Year'].apply(lambda x: x <= endYear)] beginYear = (simulationBegin + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x : x >= beginYear)] + costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] if not capital: del costs['Capital'] costs = costs.groupby('Year').sum() return costs -def simulation_annual_costs_present_value(outputDb, capital=True, truncate=True): + +def simulation_annual_costs_present_value( + outputDb, capital=True, truncate=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ df = simulation_annual_costs(outputDb, capital, truncate) for year in df.index: - df.loc[year, :] = df.loc[year, :] / (1 + default_discount_rate) ** (year - df.index[0]) + df.loc[year, :] = df.loc[year, :] / \ + (1 + default_discount_rate) ** (year - df.index[0]) return df + def simulation_benefit(outputDb): """Input : sqlite output database Output : cumulative sum of total income and total expense (= - expenditures + income) when all reactors of the simulation are taken into account """ costs = - simulation_annual_costs(outputDb).sum(axis=1) - power_gen = simulation_power_generated(outputDb) * simulation_average_lcoe(outputDb)['Average LCOE'] + power_gen = simulation_power_generated( + outputDb) * simulation_average_lcoe(outputDb)['Average LCOE'] rtn = pd.concat([costs, power_gen], axis=1).fillna(0) rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() actualization = actualization_vector(len(rtn)) @@ -973,6 +1148,7 @@ def simulation_benefit(outputDb): rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() return rtn + def simulation_period_costs(outputDb, t0=0, period=20, capital=True): """Input : sqlite output database, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of total expense in [t+t0, t+t0+period] divided by total actualized power generated in [t+t0, t+t0+period] when all reactors of the simulation are taken into account @@ -986,9 +1162,20 @@ def simulation_period_costs(outputDb, t0=0, period=20, capital=True): dfEcoInfo = evaler.eval('EconomicInfo') simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = simulation_annual_costs(outputDb, capital, truncate=False).sum(axis=1) + costs = simulation_annual_costs( + outputDb, + capital, + truncate=False).sum( + axis=1) power = simulation_power_generated(outputDb, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -999,14 +1186,25 @@ def simulation_period_costs(outputDb, t0=0, period=20, capital=True): rtn['Payment'] = pd.Series() rtn = rtn.fillna(0) for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) + rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * (1 + default_discount_rate) - df.loc[j -1 + t0, 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, + 'Power'] = rtn.loc[j - 1, + 'Power'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, + 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, + 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, + 'Payment'] = rtn.loc[j - 1, + 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, + 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, + 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn + def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): """Just for tests : another method to calculate the period costs """ @@ -1019,9 +1217,20 @@ def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): dfEcoInfo = evaler.eval('EconomicInfo') simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = simulation_annual_costs(outputDb, capital, truncate=False).sum(axis=1) + costs = simulation_annual_costs( + outputDb, + capital, + truncate=False).sum( + axis=1) power = simulation_power_generated(outputDb, truncate=False) - df = pd.DataFrame(index=list(range(initialYear, initialYear + duration // 12 + 1))) + df = pd.DataFrame( + index=list( + range( + initialYear, + initialYear + + duration // + 12 + + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -1033,11 +1242,14 @@ def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): rtn = rtn.fillna(0) for j in range(simulationBegin, simulationEnd + 1): for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn ['Power'] * (rtn['Power'] > 1) + rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ + (1 + default_discount_rate) ** (i - j) + rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ + (1 + default_discount_rate) ** (i - j) + rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn + def simulation_power_generated(outputDb, truncate=True): """Input : sqlite output database Output : Electricity generated in MWh every years by all the reactors of the simulation @@ -1052,16 +1264,21 @@ def simulation_power_generated(outputDb, truncate=True): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] + reactorIds = dfEntry[dfEntry['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() dfPower = evaler.eval('TimeSeriesPower').reset_index() dfPower = dfPower[dfPower['AgentId'].apply(lambda x: x in reactorIds)] dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, initialYear + (initialMonth + duration) // 12 + 1))) + rtn = pd.Series(dfPower['Value'] * 8760 / 12, + index=list(range(initialYear, + initialYear + (initialMonth + duration) // 12 + 1))) rtn.name = 'Power in MWh' return rtn.fillna(0) + def simulation_lcoe(outputDb): """Input : sqlite output database Output : Value corresponding to Levelized Cost of Electricity ($/MWh) when taking into account all reactors commissioned in the simulation @@ -1075,7 +1292,9 @@ def simulation_lcoe(outputDb): powerGenerated = simulation_power_generated(outputDb) actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / ((powerGenerated * actualization).fillna(0).sum()) + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ + ((powerGenerated * actualization).fillna(0).sum()) + def simulation_average_lcoe(outputDb): """Input : sqlite output database and region agent id @@ -1091,8 +1310,10 @@ def simulation_average_lcoe(outputDb): simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply(lambda x: x>simulationBegin and x simulationBegin and x < simulationEnd)] + reactorIds = dfEntry[dfEntry['Spec'].apply( + lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear dfPower = evaler.eval('TimeSeriesPower') @@ -1103,16 +1324,27 @@ def simulation_average_lcoe(outputDb): rtn['Temp2'] = pd.Series() for id in reactorIds: tmp = lcoe(outputDb, id) - commissioning = dfEntry[dfEntry.AgentId==id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId==id]['Lifetime'].iloc[0] - decommissioning = (commissioning + lifetime + initialMonth - 1) // 12 + initialYear + commissioning = dfEntry[dfEntry.AgentId == id]['EnterTime'].iloc[0] + lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'].iloc[0] + decommissioning = (commissioning + lifetime + + initialMonth - 1) // 12 + initialYear commissioning = (commissioning + initialMonth - 1) // 12 + initialYear - power = dfPower[dfPower.AgentId==id]['Value'].iloc[0] - rtn['Temp'] = pd.Series(tmp, index=list(range(commissioning, decommissioning + 1))) * power + power = dfPower[dfPower.AgentId == id]['Value'].iloc[0] + rtn['Temp'] = pd.Series( + tmp, + index=list( + range( + commissioning, + decommissioning + 1))) * power rtn['Weighted sum'] += rtn['Temp'].fillna(0) - rtn['Temp2'] = pd.Series(power, index=list(range(commissioning, decommissioning + 1))) + rtn['Temp2'] = pd.Series( + power, + index=list( + range( + commissioning, + decommissioning + + 1))) rtn['Power'] += rtn['Temp2'].fillna(0) - print(id) # test + print(id) # test rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) - diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index a9d8d3b4..412c20ce 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -40,19 +40,9 @@ def load_economic_info(self, eco_input): data = yaml.load(stream, Loader=yaml.FullLoader) self.dict = data - def update_prop(self, proto, traveling_dict, key, properties, prop_list): - updated = False - if key in traveling_dict: - for agent in traveling_dict[key]: - if agent["prototype"] == proto: - traveling_dict = agent - updated = True - for prop in prop_list: - if prop in traveling_dict: - properties[prop] = traveling_dict[prop] - return updated, traveling_dict - def get_prototype_eco(self, filiation): + """ Return a dict with all the colapsed properties of a prototype + """ proto_eco = {} traveling_dict = self.dict["eco_model"] for prop in eco_properties: @@ -61,25 +51,27 @@ def get_prototype_eco(self, filiation): for proto in filiation: updated = False - updated, traveling_dict = self.update_prop(proto, traveling_dict, - "region", proto_eco, - eco_props_region) + updated, traveling_dict = update_prop(proto, traveling_dict, + "region", proto_eco, + eco_props_region) if not updated: - updated, traveling_dict = self.update_prop(proto, - traveling_dict, - "institution", - proto_eco, - eco_props_agents) + updated, traveling_dict = update_prop(proto, + traveling_dict, + "institution", + proto_eco, + eco_props_agents) if not updated: - updated, traveling_dict = self.update_prop(proto, - traveling_dict, - "facility", - proto_eco, - eco_props_agents) + updated, traveling_dict = update_prop(proto, + traveling_dict, + "facility", + proto_eco, + eco_props_agents) return proto_eco def get_prototypes_eco(self): + """ Return a dict with all the colapsed properties of a prototype + """ proto_eco = {} model_dict = self.dict["eco_model"] @@ -100,12 +92,20 @@ def get_prototypes_eco(self): return proto_eco -finance_col = ["discount_rate", "tax_rate", "return_on_debt", - "return_on_equity"] -capital_col = ["beforePeak", "afterPeak", "constructionDuration", - "overnight_cost", "capital_dev"] -operation_col = ["fixed", "variable", "operation_dev"] -fuel_col = ["name", "supply_cost", "waste_fee", "fuel_dev"] +def update_prop(proto, traveling_dict, key, properties, prop_list): + """ load/update the economical property of the prototype from the passed + dict. + """ + updated = False + if key in traveling_dict: + for agent in traveling_dict[key]: + if agent["prototype"] == proto: + traveling_dict = agent + updated = True + for prop in prop_list: + if prop in traveling_dict: + properties[prop] = traveling_dict[prop] + return updated, traveling_dict def build_eco_row(proto_dict): @@ -130,8 +130,7 @@ def build_eco_row(proto_dict): fuel_type["name"], float(fuel_type["supply_cost"]), float(fuel_type["waste_fee"]), - float(fuel_type["deviation"])) - ], + float(fuel_type["deviation"]))], dtype=ensure_dt_bytes([ ('discount_rate', ' Date: Fri, 29 May 2020 17:39:30 -0500 Subject: [PATCH 45/64] some formating and function fixing --- cymetric/eco_metrics.py | 242 ++++++++++++++++++---------- cymetric/eco_tools.py | 58 +++++-- tests/parameters.yml | 20 +-- tests/test_eco_metrics.py | 323 +++++++++++++++++++------------------- 4 files changed, 379 insertions(+), 264 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 597a1458..3b26b436 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -107,7 +107,7 @@ def capital_cost(dfPower, dfEntry, dfInfo): del _ccdeps, _ccschema -_fcdeps = ['Resources', 'Transactions', 'EconomicInfo'] +_fcdeps = ['Resources', 'Transactions', 'AgentEntry'] _fcschema = [ ('SimId', ts.UUID), @@ -119,7 +119,7 @@ def capital_cost(dfPower, dfEntry, dfInfo): @metric(name='FuelCost', depends=_fcdeps, schema=_fcschema) -def fuel_cost(dfResources, dfTransactions, dfEcoInfo): +def fuel_cost(dfResources, dfTransactions, dfEntry): """The FuelCost metric gives the cash flows at each time step corresponding to the reactors fuel costs. It also contains the waste fee. """ @@ -130,22 +130,29 @@ def fuel_cost(dfResources, dfTransactions, dfEcoInfo): agents_eco_prop = eco_data.get_prototypes_eco() + print("agents_eco", agents_eco_prop) # add quantity to Transaction base_col = ['SimId', 'ResourceId'] added_col = base_col + ['Quantity'] rtn = merge(rtn, base_col, dfResources, added_col) + base_col = ['SimId', 'AgentId'] + added_col = base_col + ['Prototype'] + print(rtn) + print(dfEntry) + rtn = merge(rtn, base_col, dfEntry, added_col) + print(rtn) # Merge Eco with Transaction per ReceiverId and commodity - base_col = ['AgentId', 'Commodity'] + base_col = ['Prototype', 'Commodity'] # , 'Finance_DiscountRate'] - added_col = base_col + ['Fuel_SupplyCost', - 'Fuel_WasteFee', 'Fuel_Deviation'] - rtn = merge(rtn, base_col, dfEcoInfo, added_col) + added_col = base_col + ['supply_cost', + 'waste_fee', 'fuel_dev'] + rtn = merge(rtn, base_col, agents_eco_prop, added_col) for index, row in rtn.iterrows(): - rtn.at[index, 'Fuel_Deviation'] *= np.random.randn(1) + rtn.at[index, 'fuel_dev'] *= np.random.randn(1) rtn['Payment'] = rtn['Quantity'] * \ - (rtn['Fuel_Deviation'] + rtn['Fuel_SupplyCost'] + rtn['Fuel_WasteFee']) + (rtn['fuel_dev'] + rtn['supply_cost'] + rtn['waste_fee']) rtn = rtn[['SimId', 'TransactionId', 'AgentId', @@ -267,7 +274,10 @@ def operation_maintenance(dfPower, dfEcoInfo): ('Truncation_End', ts.INT)] -"""The functions below aim at calculating more complex metrics than the simple cash flows corresponding to the construction, fuel, O&M and decommissioning costs. The metrics can be calculated at an agent, institution, region or simulation level. +"""The functions below aim at calculating more complex metrics than the simple +cash flows corresponding to the construction, fuel, O&M and decommissioning +costs. The metrics can be calculated at an agent, institution, region or +simulation level. """ ####################################### # Metrics derived from the cash flows # @@ -277,7 +287,9 @@ def operation_maintenance(dfPower, dfEcoInfo): # Reactor level def annual_costs(outputDb, reactorId, capital=True): - """Input : sqlite output database and reactor's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactor is supposed to have been built before the beginning of the simulation. + """Input : sqlite output database and reactor's AgentId. It is possible not + to take into account the construction costs (capital=False) if the reactor + is supposed to have been built before the beginning of the simulation. Output : total reactor costs per year over its lifetime. """ db = dbopen(outputDb) @@ -298,8 +310,8 @@ def annual_costs(outputDb, reactorId, capital=True): costs = pd.DataFrame( {'Capital': dfCapitalCosts['Payment']}, index=list(range(duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts.AgentId == reactorId].copy( - ) + dfDecommissioningCosts = dfDecommissioningCosts[ + dfDecommissioningCosts.AgentId == reactorId].copy() dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance') @@ -319,7 +331,8 @@ def annual_costs(outputDb, reactorId, capital=True): def annual_costs_present_value(outputDb, reactorId, capital=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION """ costs = annual_costs(outputDb, reactorId, capital) actualization = actualization_vector(len(costs)) @@ -329,7 +342,8 @@ def annual_costs_present_value(outputDb, reactorId, capital=True): def average_cost(outputDb, reactorId, capital=True): """Input : sqlite output database, reactor's AgentId - Output : value (in $/MWh) corresponding to the total costs (sum of annual costs) divided by the total power generated. + Output : value (in $/MWh) corresponding to the total costs (sum of annual + costs) divided by the total power generated. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -342,7 +356,8 @@ def average_cost(outputDb, reactorId, capital=True): def benefit(outputDb, reactorId): """Input : sqlite output database and reactor agent id - Output : cumulative sum of actualized income and expense (= - expenditures + income) + Output : cumulative sum of actualized income and expense + (= - expenditures + income) """ costs = - annual_costs(outputDb, reactorId).sum(axis=1) powerGenerated = power_generated( @@ -374,7 +389,9 @@ def lcoe(outputDb, reactorId, capital=True): def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): """Input : sqlite output database, reactor id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] + Output : cost at each time step t corresponding to actualized sum of + expense in [t+t0, t+t0+period] divided by actualized power generated + in [t+t0, t+t0+period] """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -413,8 +430,10 @@ def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): df.loc[j - 1 + period + t0, 'Power'] / \ (1 + default_discount_rate) ** (period + t0 - 1) rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * (1 + default_discount_rate) ** ( - 1 - t0) + df.loc[j - 1 + period + t0, 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] *\ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Costs'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) actualization = actualization_vector(len(rtn)) actualization.index = rtn.index @@ -460,7 +479,7 @@ def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): (1 + default_discount_rate) ** (i - j) rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ (1 + default_discount_rate) ** (i - j) - #tmp['WasteManagement'][j] = pd.Series() + # tmp['WasteManagement'][j] = pd.Series() rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn @@ -481,7 +500,8 @@ def power_generated(outputDb, reactorId): dfPower = dfPower.groupby('Year').sum() rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, - initialYear + (initialMonth + duration) // 12 + 1))) + initialYear + (initialMonth + duration) // + 12 + 1))) return rtn.fillna(0) # Institution level @@ -489,8 +509,17 @@ def power_generated(outputDb, reactorId): def institution_annual_costs( outputDb, institutionId, capital=True, truncate=True): - """Input : sqlite output database and institution's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. - Output : total reactor costs per year over its lifetime at the institution level. + """Input : sqlite output database and institution's AgentId. It is + possible not to take into account the construction costs (capital=False) + if the reactors are supposed to have been built before the beginning of + the simulation. It is also possible to truncate the simulation results and + only have access to cash flows occurring between the two dates (begin and + end) specified in 'parameters.xml'. The truncation allows to let reactors + decommission after the end of the simulation and thus to take into account + cash flows that occur after the end of the simulation for example to + calculate the LCOE. + Output : total reactor costs per year over its lifetime at the institution + level. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -516,8 +545,8 @@ def institution_annual_costs( {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply( - lambda x: x in reactorIds)] + dfDecommissioningCosts = dfDecommissioningCosts[ + dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance').reset_index() @@ -544,7 +573,8 @@ def institution_annual_costs( def institution_annual_costs_present_value(outputDb, reactorId, capital=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION """ costs = institution_annual_costs(outputDb, institutionId, capital) actualization = actualization_vector(len(costs)) @@ -571,7 +601,9 @@ def institution_benefit(outputDb, institutionId): def institution_period_costs( outputDb, institutionId, t0=0, period=20, capital=True): """Input : sqlite output database, institution id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] + Output : cost at each time step t corresponding to actualized sum of + expense in [t+t0, t+t0+period] divided by actualized power generated in + [t+t0, t+t0+period] """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -610,16 +642,16 @@ def institution_period_costs( rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, - 'Power'] = rtn.loc[j - 1, - 'Power'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, - 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, - 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, - 'Payment'] = rtn.loc[j - 1, - 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, - 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, - 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Power'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Power'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Costs'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) actualization = actualization_vector(len(rtn)) actualization.index = rtn.index @@ -674,7 +706,8 @@ def institution_period_costs2( def institution_power_generated(outputDb, institutionId, truncate=True): """Input : sqlite output database and institution agent id - Output : Sum of electricity generated in MWh every year in the institution reactor fleet + Output : Sum of electricity generated in MWh every year in the institution + reactor fleet """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -698,7 +731,8 @@ def institution_power_generated(outputDb, institutionId, truncate=True): dfPower = dfPower.groupby('Year').sum() rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, - initialYear + (initialMonth + duration) // 12 + 1))) + initialYear + (initialMonth + duration) // + 12 + 1))) rtn.name = 'Power in MWh' return rtn.fillna(0) @@ -722,7 +756,11 @@ def institution_lcoe(outputDb, institutionId): def institution_average_lcoe(outputDb, institutionId): """Input : sqlite output database and institution agent id - Output : Variable cost corresponding at each time step (i.e. every year) to the weighted average of the reactors Levelized Cost of Electricity ($/MWh). A reactor is taken into account at a time step t only if it is active (i.e. already commissioned and not yet decommissioned) at this time step. + Output : Variable cost corresponding at each time step (i.e. every year) + to the weighted average of the reactors Levelized Cost of Electricity + ($/MWh). A reactor is taken into account at a time step t only if it is + active (i.e. already commissioned and not yet decommissioned) at this + time step. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -778,8 +816,17 @@ def institution_average_lcoe(outputDb, institutionId): def region_annual_costs(outputDb, regionId, capital=True, truncate=True): - """Input : sqlite output database and region's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. - Output : total reactor costs per year over its lifetime at the region level. + """Input : sqlite output database and region's AgentId. It is possible not + to take into account the construction costs (capital=False) if the reactors + are supposed to have been built before the beginning of the simulation. It + is also possible to truncate the simulation results and only have access + to cash flows occurring between the two dates (begin and end) specified in + 'parameters.xml'. The truncation allows to let reactors decommission after + the end of the simulation and thus to take into account cash flows that + occur after the end of the simulation for example to calculate the LCOE. + + Output : total reactor costs per year over its lifetime at the region + level. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -808,8 +855,8 @@ def region_annual_costs(outputDb, regionId, capital=True, truncate=True): {'Capital': dfCapitalCosts['Payment']}, index=list(range(duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply( - lambda x: x in reactorIds)] + dfDecommissioningCosts = dfDecommissioningCosts[ + dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance').reset_index() @@ -837,7 +884,8 @@ def region_annual_costs(outputDb, regionId, capital=True, truncate=True): def region_annual_costs_present_value( outputDb, regionId, capital=True, truncate=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION """ costs = region_annual_costs(outputDb, regionId, capital) actualization = actualization_vector(len(costs)) @@ -847,11 +895,12 @@ def region_annual_costs_present_value( def region_benefit(outputDb, regionId): """Input : sqlite output database and region agent id - Output : cumulative sum of actualized income and expense (= - expenditures + income) + Output : cumulative sum of actualized income and expense + (= - expenditures + income) """ costs = - region_annual_costs(outputDb, regionId).sum(axis=1) - power_gen = region_power_generated( - outputDb, regionId) * region_average_lcoe(outputDb, regionId)['Average LCOE'] + power_gen = region_power_generated(outputDb, regionId) * \ + region_average_lcoe(outputDb, regionId)['Average LCOE'] rtn = pd.concat([costs, power_gen], axis=1).fillna(0) rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() actualization = actualization_vector(len(rtn)) @@ -862,7 +911,9 @@ def region_benefit(outputDb, regionId): def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): """Input : sqlite output database, region id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] + Output : cost at each time step t corresponding to actualized sum of + expense in [t+t0, t+t0+period] divided by actualized power generated + in [t+t0, t+t0+period] """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -899,16 +950,16 @@ def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd + 1): - rtn.loc[j, - 'Power'] = rtn.loc[j - 1, - 'Power'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, - 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, - 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, - 'Payment'] = rtn.loc[j - 1, - 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, - 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, - 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Power'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Power'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Costs'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) actualization = actualization_vector(len(rtn)) actualization.index = rtn.index @@ -960,7 +1011,8 @@ def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): def region_power_generated(outputDb, regionId, truncate=True): """Input : sqlite output database and region agent id - Output : Sum of electricity generated in MWh every years in the region reactor fleet + Output : Sum of electricity generated in MWh every years in the region + reactor fleet """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -987,7 +1039,8 @@ def region_power_generated(outputDb, regionId, truncate=True): dfPower = dfPower.groupby('Year').sum() rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, - initialYear + (initialMonth + duration) // 12 + 1))) + initialYear + (initialMonth + duration) // + 12 + 1))) rtn.name = 'Power in MWh' return rtn.fillna(0) @@ -1011,7 +1064,11 @@ def region_lcoe(outputDb, regionId): def region_average_lcoe(outputDb, regionId): """Input : sqlite output database and region agent id - Output : Variable cost corresponding at each time step (i.e. every year) to the weighted average of the reactors Levelized Cost of Electricity ($/MWh). A reactor is taken into account at a time step t if and only if it is active (i.e. already commissioned and not yet decommissioned) at this time step. + Output : Variable cost corresponding at each time step (i.e. every year) + to the weighted average of the reactors Levelized Cost of Electricity + ($/MWh). A reactor is taken into account at a time step t if and only if + it is active (i.e. already commissioned and not yet decommissioned) at + this time step. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -1070,8 +1127,16 @@ def region_average_lcoe(outputDb, regionId): def simulation_annual_costs(outputDb, capital=True, truncate=True): - """Input : sqlite output database. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors decommission after the end of the simulation and thus to take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. - Output : total reactor costs per year over its lifetime at the simulation level. + """Input : sqlite output database. It is possible not to take into account + the construction costs (capital=False) if the reactors are supposed to + have been built before the beginning of the simulation. It is also + possible to truncate the simulation results and only have access to cash + flows occurring between the two dates (begin and end) specified in + 'parameters.xml'. The truncation allows to let reactors decommission after + the end of the simulation and thus to take into account cash flows that + occur after the end of the simulation for example to calculate the LCOE. + Output : total reactor costs per year over its lifetime at the simulation + level. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -1096,8 +1161,8 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[dfDecommissioningCosts['AgentId'].apply( - lambda x: x in reactorIds)] + dfDecommissioningCosts = dfDecommissioningCosts[ + dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] dfOMCosts = evaler.eval('OperationMaintenance').reset_index() @@ -1125,7 +1190,8 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): def simulation_annual_costs_present_value( outputDb, capital=True, truncate=True): - """Same as annual_cost except all values are actualized to the begin date of the SIMULATION + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION """ df = simulation_annual_costs(outputDb, capital, truncate) for year in df.index: @@ -1136,7 +1202,9 @@ def simulation_annual_costs_present_value( def simulation_benefit(outputDb): """Input : sqlite output database - Output : cumulative sum of total income and total expense (= - expenditures + income) when all reactors of the simulation are taken into account + Output : cumulative sum of total income and total expense + (= - expenditures + income) when all reactors of the simulation + are taken into account """ costs = - simulation_annual_costs(outputDb).sum(axis=1) power_gen = simulation_power_generated( @@ -1151,7 +1219,10 @@ def simulation_benefit(outputDb): def simulation_period_costs(outputDb, t0=0, period=20, capital=True): """Input : sqlite output database, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of total expense in [t+t0, t+t0+period] divided by total actualized power generated in [t+t0, t+t0+period] when all reactors of the simulation are taken into account + Output : cost at each time step t corresponding to actualized sum of total + expense in [t+t0, t+t0+period] divided by total actualized power generated + in [t+t0, t+t0+period] when all reactors of the simulation are taken into + account """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -1191,16 +1262,16 @@ def simulation_period_costs(outputDb, t0=0, period=20, capital=True): rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ (1 + default_discount_rate) ** (i - simulationBegin) for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, - 'Power'] = rtn.loc[j - 1, - 'Power'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, - 'Power'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, - 'Power'] / (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, - 'Payment'] = rtn.loc[j - 1, - 'Payment'] * (1 + default_discount_rate) - df.loc[j - 1 + t0, - 'Costs'] * (1 + default_discount_rate) ** (1 - t0) + df.loc[j - 1 + period + t0, - 'Costs'] / (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Power'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Power'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) + rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ + (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * \ + (1 + default_discount_rate) ** (1 - t0) + \ + df.loc[j - 1 + period + t0, 'Costs'] / \ + (1 + default_discount_rate) ** (period + t0 - 1) rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) return rtn @@ -1252,7 +1323,8 @@ def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): def simulation_power_generated(outputDb, truncate=True): """Input : sqlite output database - Output : Electricity generated in MWh every years by all the reactors of the simulation + Output : Electricity generated in MWh every years by all the reactors of + the simulation """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -1274,14 +1346,16 @@ def simulation_power_generated(outputDb, truncate=True): dfPower = dfPower.groupby('Year').sum() rtn = pd.Series(dfPower['Value'] * 8760 / 12, index=list(range(initialYear, - initialYear + (initialMonth + duration) // 12 + 1))) + initialYear + (initialMonth + duration) // + 12 + 1))) rtn.name = 'Power in MWh' return rtn.fillna(0) def simulation_lcoe(outputDb): """Input : sqlite output database - Output : Value corresponding to Levelized Cost of Electricity ($/MWh) when taking into account all reactors commissioned in the simulation + Output : Value corresponding to Levelized Cost of Electricity ($/MWh) when + taking into account all reactors commissioned in the simulation """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) @@ -1298,7 +1372,11 @@ def simulation_lcoe(outputDb): def simulation_average_lcoe(outputDb): """Input : sqlite output database and region agent id - Output : Variable cost corresponding at each time step (i.e. every year) to the weighted average of the reactors Levelized Cost of Electricity ($/MWh). A reactor is taken into account at a time step t if and only if it is in activity (i.e. already commissioned and not yet decommissioned) at this time step. + Output : Variable cost corresponding at each time step (i.e. every year) + to the weighted average of the reactors Levelized Cost of Electricity + ($/MWh). A reactor is taken into account at a time step t if and only if + it is in activity (i.e. already commissioned and not yet decommissioned) + at this time step. """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 412c20ce..ac3f48e6 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -23,7 +23,7 @@ capital_col = ["beforePeak", "afterPeak", "constructionDuration", "overnight_cost", "capital_dev"] operation_col = ["fixed", "variable", "operation_dev"] -fuel_col = ["name", "supply_cost", "waste_fee", "fuel_dev"] +fuel_col = ["Commodity", "supply_cost", "waste_fee", "fuel_dev"] class eco_input_data(): @@ -72,24 +72,58 @@ def get_prototype_eco(self, filiation): def get_prototypes_eco(self): """ Return a dict with all the colapsed properties of a prototype """ + row_col = ["Prototype"] + finance_col + \ + capital_col + operation_col + fuel_col + df_eco = pd.DataFrame(columns=row_col) + proto_eco = {} model_dict = self.dict["eco_model"] + # Set default eco data for prop in eco_properties: if prop in model_dict: proto_eco[prop] = model_dict[prop] + # Retrieve Regions eco data for region_dict in model_dict["region"]: region_eco = proto_eco region_eco["prototype"] = region_dict["prototype"] + # get region Properties for prop in eco_properties: if prop in region_dict: proto_eco[prop] = region_dict[prop] - print(region_eco) - region_raw = build_eco_row(region_eco) - print(region_raw) - - return proto_eco + # build pdf with facility properties + region_pdf = build_eco_prot(region_eco) + df_eco = pd.concat([region_pdf, df_eco], + ignore_index=True, sort=False) + + # Retrieve Institutions eco data + for institution_dict in region_dict["institution"]: + institution_eco = region_eco + institution_eco["prototype"] = institution_dict["prototype"] + # get institution Properties + for prop in eco_properties: + if prop in institution_dict: + proto_eco[prop] = institution_dict[prop] + # build pdf with facility properties + inst_pdf = build_eco_prot(institution_eco) + df_eco = pd.concat([inst_pdf, df_eco], + ignore_index=True, sort=False) + + # Retrieve Facilities eco data + for facility_dict in institution_dict["facility"]: + facility_eco = institution_eco + facility_eco["prototype"] = facility_dict["prototype"] + # get facility Properties + for prop in eco_properties: + if prop in facility_dict: + proto_eco[prop] = facility_dict[prop] + # build pdf with facility properties + inst_pdf = build_eco_prot(facility_eco) + df_eco = pd.concat([inst_pdf, df_eco], + ignore_index=True, sort=False) + + return df_eco def update_prop(proto, traveling_dict, key, properties, prop_list): @@ -108,13 +142,14 @@ def update_prop(proto, traveling_dict, key, properties, prop_list): return updated, traveling_dict -def build_eco_row(proto_dict): - row_col = finance_col + capital_col + operation_col + fuel_col - print(row_col) +def build_eco_prot(proto_dict): + row_col = ["prototype"] + finance_col + \ + capital_col + operation_col + fuel_col df = pd.DataFrame(columns=row_col) - + print(proto_dict) for fuel_type in proto_dict["fuels"]: a_row = pd.DataFrame(np.array([( + proto_dict["prototype"], float(proto_dict["finance"]["discount_rate"]), float(proto_dict["finance"]["tax_rate"]), float(proto_dict["finance"]["return_on_debt"]), @@ -132,6 +167,7 @@ def build_eco_row(proto_dict): float(fuel_type["waste_fee"]), float(fuel_type["deviation"]))], dtype=ensure_dt_bytes([ + ('Prototype', 'O'), ('discount_rate', ' Date: Fri, 29 May 2020 17:49:15 -0500 Subject: [PATCH 46/64] fix line length --- tests/test_eco_metrics.py | 62 +++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index fb07278b..f8d6fbfd 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -327,25 +327,32 @@ def test_annual_costs(): """ """ # Reactor / Institution level - assert_equal(eco_metrics.annual_costs('tests/test.sqlite', 15).sum().sum(), - eco_metrics.institution_annual_costs('tests/test.sqlite', 16).sum().sum()) - assert_equal(eco_metrics.annual_costs_present_value('tests/test.sqlite', 13).sum().sum(), - eco_metrics.institution_annual_costs_present_value( - 'tests/test.sqlite', 9).sum().sum()) + assert_equal( + eco_metrics.annual_costs('tests/test.sqlite', 15).sum(), + eco_metrics.institution_annual_costs('tests/test.sqlite', 16).sum()) + assert_equal( + eco_metrics.annual_costs_present_value('tests/test.sqlite', 13).sum(), + eco_metrics.institution_annual_costs_present_value('tests/test.sqlite', + 9).sum().sum()) # Region / Institution level - assert_equal(eco_metrics.region_annual_costs('tests/test.sqlite', 8).sum().sum(), - eco_metrics.institution_annual_costs('tests/test.sqlite', 9).sum().sum()) - assert_equal(eco_metrics.region_annual_costs_present_value( - 'tests/test.sqlite', 8).sum().sum(), + assert_equal( + eco_metrics.region_annual_costs('tests/test.sqlite', 8).sum().sum(), + eco_metrics.institution_annual_costs('tests/test.sqlite', + 9).sum().sum()) + assert_equal( + eco_metrics.region_annual_costs_present_value( + 'tests/test.sqlite', 8).sum().sum(), eco_metrics.institution_annual_costs_present_value( - 'tests/test.sqlite', 9).sum().sum()) + 'tests/test.sqlite', 9).sum().sum()) # Simulation / Reactor level - assert_equal(eco_metrics.region_annual_costs('tests/test.sqlite', 8).sum().sum(), - eco_metrics.simulation_annual_costs('tests/test.sqlite').sum().sum()) - assert_equal(eco_metrics.region_annual_costs_present_value( - 'tests/test.sqlite', 8).sum().sum(), + assert_equal( + eco_metrics.region_annual_costs('tests/test.sqlite', 8).sum(), + eco_metrics.simulation_annual_costs('tests/test.sqlite').sum().sum()) + assert_equal( + eco_metrics.region_annual_costs_present_value( + 'tests/test.sqlite', 8).sum().sum(), eco_metrics.simulation_annual_costs_present_value( - 'tests/test.sqlite').sum().sum()) + 'tests/test.sqlite').sum().sum()) def test_lcoe(): @@ -395,10 +402,12 @@ def test_power_generated(): """ # Reactor / Institution level assert_equal(eco_metrics.power_generated('tests/test.sqlite', 13), - eco_metrics.institution_power_generated('tests/test.sqlite', 9)) + eco_metrics.institution_power_generated('tests/test.sqlite', + 9)) # Region / Institution level assert_equal(eco_metrics.region_power_generated('tests/test.sqlite', 8), - eco_metrics.institution_power_generated('tests/test.sqlite', 9)) + eco_metrics.institution_power_generated('tests/test.sqlite', + 9)) # Simulation / Reactor level assert_equal(eco_metrics.region_power_generated('tests/test.sqlite', 8), eco_metrics.simulation_power_generated('tests/test.sqlite')) @@ -408,17 +417,20 @@ def test_period_costs(): """ """ # Reactor level - assert_equal(eco_metrics.period_costs('tests/test.sqlite', 13, 30).sum().sum(), - eco_metrics.period_costs2('tests/test.sqlite', 13, 30).sum().sum()) + assert_equal(eco_metrics.period_costs('tests/test.sqlite', 13, 30).sum(), + eco_metrics.period_costs2('tests/test.sqlite', 13, 30).sum()) # Reactor / Institution level - assert_equal(eco_metrics.period_costs('tests/test.sqlite', 13).sum().sum(), - eco_metrics.institution_period_costs('tests/test.sqlite', 9).sum().sum()) + assert_equal(eco_metrics.period_costs('tests/test.sqlite', 13).sum(), + eco_metrics.institution_period_costs('tests/test.sqlite', + 9).sum()) # Region / Institution level - assert_equal(eco_metrics.region_period_costs('tests/test.sqlite', 8).sum().sum(), - eco_metrics.institution_period_costs('tests/test.sqlite', 9).sum().sum()) + assert_equal(eco_metrics.region_period_costs('tests/test.sqlite', 8).sum(), + eco_metrics.institution_period_costs('tests/test.sqlite', + 9).sum()) # Region / Simulation level - assert_equal(eco_metrics.region_period_costs('tests/test.sqlite', 8).sum().sum(), - eco_metrics.simulation_period_costs('tests/test.sqlite').sum().sum()) + assert_equal(eco_metrics.region_period_costs('tests/test.sqlite', 8).sum(), + eco_metrics.simulation_period_costs( + 'tests/test.sqlite').sum()) if __name__ == "__main__": From 80fced220fb517af26801559a134ca24a46ff22d Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Mon, 1 Jun 2020 12:15:52 -0500 Subject: [PATCH 47/64] fuel cost test working --- cymetric/eco_metrics.py | 10 +++---- tests/parameters.yml | 2 +- tests/test_eco_metrics.py | 61 +++++++++++++++++---------------------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 3b26b436..cd56df14 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -128,23 +128,21 @@ def fuel_cost(dfResources, dfTransactions, dfEntry): # in agreement, taking receiver (using implementation as ref) rtn = dfTransactions.rename(columns={'ReceiverId': 'AgentId'}) + # Get eco data agents_eco_prop = eco_data.get_prototypes_eco() - print("agents_eco", agents_eco_prop) - # add quantity to Transaction + # Add quantity to Transaction base_col = ['SimId', 'ResourceId'] added_col = base_col + ['Quantity'] rtn = merge(rtn, base_col, dfResources, added_col) + + # Adding prototype info base_col = ['SimId', 'AgentId'] added_col = base_col + ['Prototype'] - print(rtn) - print(dfEntry) rtn = merge(rtn, base_col, dfEntry, added_col) - print(rtn) # Merge Eco with Transaction per ReceiverId and commodity base_col = ['Prototype', 'Commodity'] - # , 'Finance_DiscountRate'] added_col = base_col + ['supply_cost', 'waste_fee', 'fuel_dev'] rtn = merge(rtn, base_col, agents_eco_prop, added_col) diff --git a/tests/parameters.yml b/tests/parameters.yml index 5a4831f3..d52f7808 100644 --- a/tests/parameters.yml +++ b/tests/parameters.yml @@ -77,7 +77,7 @@ eco_model: - prototype: Reactor1 fuels: - name: uox - supply_cost: 10.5 + supply_cost: 1 waste_fee: 0 deviation: 0 diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index f8d6fbfd..168253e6 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -60,13 +60,13 @@ def test_fuel_cost(): (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 5, 12, 'uox', 1, 6), (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 6, 12, 'uox', 1, 7), (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 7, 12, 'uox', 1, 8), - (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 8, 12, 'uox', 1, 9) - ], dtype=ensure_dt_bytes([('SimId', 'O'), - ('TransactionId', ' Date: Mon, 1 Jun 2020 17:19:46 -0500 Subject: [PATCH 48/64] decommision working --- cymetric/eco_metrics.py | 24 ++++++++++++------------ cymetric/eco_tools.py | 32 ++++++++++++++++++++------------ tests/parameters.yml | 3 +++ tests/test_eco_metrics.py | 37 +++++++++++++++++++++---------------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index cd56df14..dec4cfc7 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -163,7 +163,7 @@ def fuel_cost(dfResources, dfTransactions, dfEntry): del _fcdeps, _fcschema -_dcdeps = ['TimeSeriesPower', 'AgentEntry', 'Info', 'EconomicInfo'] +_dcdeps = ['TimeSeriesPower', 'AgentEntry', 'Info'] _dcschema = [ ('SimId', ts.UUID), @@ -173,27 +173,27 @@ def fuel_cost(dfResources, dfTransactions, dfEntry): @metric(name='DecommissioningCost', depends=_dcdeps, schema=_dcschema) -def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): +def decommissioning_cost(dfPower, dfEntry, dfInfo): """The Decommissioning cost metric gives the cash flows at each time step corresponding to the reactors decommissioning. """ + # Get eco data + dfEcoInfo = eco_data.get_prototypes_eco() - base_col = ['AgentId'] - added_col = base_col + ['Value'] - dfEcoInfo = pd.merge(dfPower[added_col], dfEcoInfo, on=base_col) - dfEcoInfo.rename(columns={'Value': 'PowerCapacity'}, inplace=True) dfEntry = dfEntry[dfEntry['Lifetime'].apply(lambda x: x > 0)] reactorsId = dfEntry[dfEntry['Spec'].apply( lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() rtn = pd.DataFrame() for id in reactorsId: - tmp = dfEcoInfo[dfEntry['AgentId'] == id] - if(len(tmp) == 1): - duration = int(tmp.at[0, 'Decommissioning_Duration']) - overnightCost = tmp.at[0, 'Decommissioning_OvernightCost'] + proto = dfEntry[dfEntry['AgentId'] == id].at[0, 'Prototype'] + tmp = dfEcoInfo[dfEcoInfo['Prototype'] == proto].reset_index() + if (len(tmp) == 1): + duration = int(tmp.at[0, 'decom_duration']) + overnightCost = tmp.at[0, 'decom_overnight_cost'] cashFlowShape = capital_shape( duration - duration // 2, duration // 2) - powerCapacity = tmp.at[0, 'PowerCapacity'] + powerCapacity = dfPower[dfPower['AgentId'] + == id].reset_index().at[0, 'Value'] cashFlow = cashFlowShape * powerCapacity * overnightCost entryTime = dfEntry[dfEntry.AgentId == id]['EnterTime'][0] lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'][0] @@ -218,7 +218,7 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo, dfEcoInfo): ('Payment', ts.DOUBLE)] -@metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) +@ metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) def operation_maintenance(dfPower, dfEcoInfo): """The OperationMaintenance metric gives the cash flows at each time step corresponding to the reactor operations and maintenance costs. diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index ac3f48e6..80395497 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -18,12 +18,14 @@ eco_props_region = ["finance"] + eco_props_agents eco_properties = ["periode"] + eco_props_region -finance_col = ["discount_rate", "tax_rate", "return_on_debt", - "return_on_equity"] -capital_col = ["beforePeak", "afterPeak", "constructionDuration", - "overnight_cost", "capital_dev"] -operation_col = ["fixed", "variable", "operation_dev"] -fuel_col = ["Commodity", "supply_cost", "waste_fee", "fuel_dev"] + +key_option_dict = {"finance": ["discount_rate", "tax_rate", "return_on_debt", + "return_on_equity"], + "capital": ["beforePeak", "afterPeak", "constructionDuration", + "capital_overnight_cost", "capital_dev"], + "operation": ["fixed", "variable", "operation_dev"], + "decommission": ["decom_duration", "decom_overnight_cost"], + "fuel": ["Commodity", "supply_cost", "waste_fee", "fuel_dev"]} class eco_input_data(): @@ -72,8 +74,9 @@ def get_prototype_eco(self, filiation): def get_prototypes_eco(self): """ Return a dict with all the colapsed properties of a prototype """ - row_col = ["Prototype"] + finance_col + \ - capital_col + operation_col + fuel_col + row_col = ["Prototype"] + for key in key_option_dict: + row_col += key_option_dict[key] df_eco = pd.DataFrame(columns=row_col) proto_eco = {} @@ -143,10 +146,11 @@ def update_prop(proto, traveling_dict, key, properties, prop_list): def build_eco_prot(proto_dict): - row_col = ["prototype"] + finance_col + \ - capital_col + operation_col + fuel_col + row_col = ["Prototype"] + for key in key_option_dict: + row_col += key_option_dict[key] + df = pd.DataFrame(columns=row_col) - print(proto_dict) for fuel_type in proto_dict["fuels"]: a_row = pd.DataFrame(np.array([( proto_dict["prototype"], @@ -162,6 +166,8 @@ def build_eco_prot(proto_dict): float(proto_dict["operation_maintenance"]["fixed"]), float(proto_dict["operation_maintenance"]["variable"]), float(proto_dict["operation_maintenance"]["deviation"]), + float(proto_dict["decommission"]["duration"]), + float(proto_dict["decommission"]["overnight_cost"]), fuel_type["name"], float(fuel_type["supply_cost"]), float(fuel_type["waste_fee"]), @@ -175,11 +181,13 @@ def build_eco_prot(proto_dict): ('beforePeak', ' Date: Tue, 2 Jun 2020 13:46:16 -0500 Subject: [PATCH 49/64] fixing operation maintenance --- cymetric/eco_metrics.py | 31 ++-- tests/parameters.yml | 4 +- tests/test_eco_metrics.py | 376 +++++++++++++++++++------------------- 3 files changed, 211 insertions(+), 200 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index dec4cfc7..03cde521 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -210,7 +210,7 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo): del _dcdeps, _dcschema -_omdeps = ['TimeSeriesPower', 'EconomicInfo'] +_omdeps = ['TimeSeriesPower', 'AgentEntry'] _omschema = [('SimId', ts.UUID), ('AgentId', ts.INT), @@ -218,27 +218,36 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo): ('Payment', ts.DOUBLE)] -@ metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) -def operation_maintenance(dfPower, dfEcoInfo): +@metric(name='OperationMaintenance', depends=_omdeps, schema=_omschema) +def operation_maintenance(dfPower, dfEntry): """The OperationMaintenance metric gives the cash flows at each time step corresponding to the reactor operations and maintenance costs. """ exp = ['SimId', 'AgentId', 'Time', 'Payment'] power = ['SimId', 'AgentId', 'Time', 'Value'] - ecoInfo = ['AgentId', 'FixedCost', 'VariableCost', 'Operation_Deviation'] - rtn = dfEcoInfo + ecoInfo = ['fixed', 'variable', 'operation_dev'] + # Get eco data + dfEcoInfo = eco_data.get_prototypes_eco() + + # Adding prototype info + base_col = ['Prototype'] + added_col = base_col + ecoInfo + rtn = pd.merge(dfEntry, dfEcoInfo[added_col], on=base_col) + print(rtn) + for index, row in rtn.iterrows(): - rtn.at[index, 'Operation_Deviation'] *= np.random.randn(1) - rtn['FixedCost'] += rtn['Operation_Deviation'] - rtn['VariableCost'] += rtn['Operation_Deviation'] + rtn.at[index, 'operation_dev'] *= np.random.randn(1) + rtn['fixed'] += rtn['operation_dev'] + rtn['variable'] += rtn['operation_dev'] base_col = ['AgentId'] - added_col = base_col + ['SimId', 'Time', 'Value'] + added_col = base_col + ['Time', 'Value'] rtn = pd.merge(dfPower[added_col], rtn, on=base_col) rtn['Value'] *= 8760 / 12 - rtn['Payment'] = (rtn['Value'] * rtn['VariableCost'] + - max(rtn['Value']) * rtn['FixedCost']) + rtn['Payment'] = (rtn['Value'] * rtn['variable'] + + max(rtn['Value']) * rtn['fixed']) + print(rtn) return rtn[['SimId', 'AgentId', 'Time', 'Payment']] diff --git a/tests/parameters.yml b/tests/parameters.yml index 6567f736..6dbde0a0 100644 --- a/tests/parameters.yml +++ b/tests/parameters.yml @@ -50,8 +50,8 @@ eco_model: constructionDuration: 10 overnight_cost: 1 operation_maintenance: - fixed: 3 - variable: 2 + fixed: 0.5 + variable: 1 deviation: 0 fuels: - name: uox diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index a1851500..d6919c8c 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -16,34 +16,37 @@ def test_capital_cost(): - exp = pd.DataFrame(np.array([ - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 0, 0.126000), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 1, 0.139965), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 2, 0.112035), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 3, 0.084000), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 4, 0.055965), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 5, 0.028035), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 6, 0.0) - ], dtype=ensure_dt_bytes([ - ('SimId', 'O'), ('AgentId', ' Date: Tue, 2 Jun 2020 17:24:56 -0500 Subject: [PATCH 50/64] fixing yml parsing --- cymetric/eco_metrics.py | 3 - tests/test_eco_metrics.py | 258 ++++++++++++++++++++++++++------------ 2 files changed, 177 insertions(+), 84 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 03cde521..e24bf251 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -233,7 +233,6 @@ def operation_maintenance(dfPower, dfEntry): base_col = ['Prototype'] added_col = base_col + ecoInfo rtn = pd.merge(dfEntry, dfEcoInfo[added_col], on=base_col) - print(rtn) for index, row in rtn.iterrows(): rtn.at[index, 'operation_dev'] *= np.random.randn(1) @@ -246,8 +245,6 @@ def operation_maintenance(dfPower, dfEntry): rtn['Value'] *= 8760 / 12 rtn['Payment'] = (rtn['Value'] * rtn['variable'] + max(rtn['Value']) * rtn['fixed']) - - print(rtn) return rtn[['SimId', 'AgentId', 'Time', 'Payment']] diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index d6919c8c..a13ea71a 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -232,69 +232,69 @@ def test_operation_maintenance(): # something is missing to be able to match the exp DataFrame.... # def test_economic_info(): -# exp = pd.DataFrame(np.array([ -# (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 0, 25436.85), -# (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 2, 25436.85), -# (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 5, 8, 43800.0) -# ], dtype=ensure_dt_bytes([ -# ('SimId', 'O'), ('AgentId', ' Date: Wed, 3 Jun 2020 16:14:26 -0500 Subject: [PATCH 51/64] some improvement in annual costs calculation --- cymetric/eco_metrics.py | 124 +++++++++++++++++++++----------------- cymetric/eco_tools.py | 5 +- tests/test_eco_metrics.py | 60 +++++++++--------- 3 files changed, 103 insertions(+), 86 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index e24bf251..3c7ee580 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -177,10 +177,16 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo): """The Decommissioning cost metric gives the cash flows at each time step corresponding to the reactors decommissioning. """ + out_col = ['SimId', 'AgentId', 'Payment', 'Time'] # Get eco data dfEcoInfo = eco_data.get_prototypes_eco() dfEntry = dfEntry[dfEntry['Lifetime'].apply(lambda x: x > 0)] + + # if empty do nothing + if len(dfEntry) == 0: + return pd.DataFrame(columns=out_col) + reactorsId = dfEntry[dfEntry['Spec'].apply( lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() rtn = pd.DataFrame() @@ -204,7 +210,7 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo): 'Payment': cashFlow}) rtn = pd.concat([rtn, time_pdf], ignore_index=True) rtn['SimId'] = dfPower['SimId'][0] - return rtn[['SimId', 'AgentId', 'Payment', 'Time']] + return rtn[out_col] del _dcdeps, _dcschema @@ -288,9 +294,17 @@ def operation_maintenance(dfPower, dfEntry): ####################################### -# Reactor level +_omdeps = ['AgentEntry', 'CapitalCost', + 'DecommissioningCost', 'OperationMaintenance', 'FuelCost'] + +_omschema = [('SimId', ts.UUID), + ('AgentId', ts.INT), + ('Time', ts.INT), + ('Payment', ts.DOUBLE)] + -def annual_costs(outputDb, reactorId, capital=True): +@metric(name='MonthlyCosts', depends=_omdeps, schema=_omschema) +def facility_annual_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): """Input : sqlite output database and reactor's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactor is supposed to have been built before the beginning of the simulation. @@ -299,38 +313,31 @@ def annual_costs(outputDb, reactorId, capital=True): db = dbopen(outputDb) evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info') - duration = dfInfo['Duration'].iloc[0] - initialYear = dfInfo['InitialYear'].iloc[0] - initialMonth = dfInfo['InitialMonth'].iloc[0] + base_col = ['SimId', 'AgentId', 'Time'] + costs = pd.DataFrame(columns=base_col) + + costs_pairs = [(dfCapitalCost, "Capital"), + (dfDecom, "Decommision"), + (dfOM, "OperationMaintenance"), + (dfFuelCost, "Fuel")] + for pair in costs_pairs: + df_tmp = pair[0] + df_tmp = df_tmp.groupby(base_col).sum().reset_index() + df_tmp = df_tmp.rename(columns={'Payment': pair[1]}) + if (len(df_tmp) != 0): + costs = pd.merge(df_tmp, costs, + how='outer', on=base_col) + else: + costs[pair[1]] = 0 - dfEntry = evaler.eval('AgentEntry') - print(dfEntry) - commissioning = dfEntry[dfEntry.AgentId == reactorId]['EnterTime'].iloc[0] - dfCapitalCosts = evaler.eval('CapitalCost') - print(dfCapitalCosts) - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts.AgentId == reactorId].copy() - dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame( - {'Capital': dfCapitalCosts['Payment']}, index=list(range(duration))) - dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() - dfDecommissioningCosts = dfDecommissioningCosts[ - dfDecommissioningCosts.AgentId == reactorId].copy() - dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() - costs['Decommissioning'] = dfDecommissioningCosts['Payment'] - dfOMCosts = evaler.eval('OperationMaintenance') - dfOMCosts = dfOMCosts[dfOMCosts.AgentId == reactorId].copy() - dfOMCosts = dfOMCosts.groupby('Time').sum() - costs['OandM'] = dfOMCosts['Payment'] - dfFuelCosts = evaler.eval('FuelCost') - dfFuelCosts = dfFuelCosts[dfFuelCosts.AgentId == reactorId].copy() - dfFuelCosts = dfFuelCosts.groupby('Time').sum() - costs['Fuel'] = dfFuelCosts['Payment'] costs = costs.fillna(0) - costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum() + # costs['Year'] = (costs['Time'] + initialMonth - 1) // 12 + initialYear + # if not capital: + # del costs['Capital'] + # costs = costs.groupby(['Year', "AgentId"]).sum().reset_index() + # costs.drop(['Time'], axis=1, inplace=True) + + print(costs.drop(['SimId'], axis=1)) return costs @@ -387,7 +394,7 @@ def lcoe(outputDb, reactorId, capital=True): powerGenerated = power_generated(outputDb, reactorId) actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() /\ ((powerGenerated * actualization).fillna(0).sum()) @@ -519,7 +526,7 @@ def institution_annual_costs( the simulation. It is also possible to truncate the simulation results and only have access to cash flows occurring between the two dates (begin and end) specified in 'parameters.xml'. The truncation allows to let reactors - decommission after the end of the simulation and thus to take into account + decommission after the end of the simulation and thus print take into account cash flows that occur after the end of the simulation for example to calculate the LCOE. Output : total reactor costs per year over its lifetime at the institution @@ -527,51 +534,59 @@ def institution_annual_costs( """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() + dfInfo = evaler.eval('Info') duration = dfInfo['Duration'].iloc[0] initialYear = dfInfo['InitialYear'].iloc[0] initialMonth = dfInfo['InitialMonth'].iloc[0] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() + dfEcoInfo = eco_data.get_prototypes_eco() + simulationBegin = eco_data.dict["eco_model"]["periode"]["start"] + simulationEnd = eco_data.dict["eco_model"]["periode"]["end"] + dfEntry = evaler.eval('AgentEntry') dfEntry = dfEntry[dfEntry.ParentId == institutionId] dfEntry = dfEntry[dfEntry['EnterTime'].apply( lambda x: x > simulationBegin and x < simulationEnd)] + print(dfEntry) dfPower = evaler.eval('TimeSeriesPower') reactorIds = dfEntry[dfEntry['AgentId'].apply( lambda x: isreactor(dfPower, x))]['AgentId'].tolist() - dfCapitalCosts = evaler.eval('CapitalCost').reset_index() + dfCapitalCosts = evaler.eval('CapitalCost') dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( lambda x: x in reactorIds)] - dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() + print(dfCapitalCosts) + dfCapitalCosts = dfCapitalCosts.groupby( + ['AgentId', 'Time']).sum().reset_index() + print(dfCapitalCosts) + costs = pd.DataFrame( {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) - dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() + print(costs) + dfDecommissioningCosts = evaler.eval('DecommissioningCost') if not dfDecommissioningCosts.empty: dfDecommissioningCosts = dfDecommissioningCosts[ dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] - dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() + dfDecommissioningCosts = dfDecommissioningCosts.groupby( + 'AgentId').sum() costs['Decommissioning'] = dfDecommissioningCosts['Payment'] - dfOMCosts = evaler.eval('OperationMaintenance').reset_index() + dfOMCosts = evaler.eval('OperationMaintenance') dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( lambda x: x in reactorIds)] - dfOMCosts = dfOMCosts.groupby('Time').sum() - costs['OandM'] = dfOMCosts.loc[:, 'Payment'] - dfFuelCosts = evaler.eval('FuelCost').reset_index() + dfOMCosts = dfOMCosts.groupby('AgentId').sum() + costs['OperationAndMaintenance'] = dfOMCosts.loc[:, 'Payment'] + dfFuelCosts = evaler.eval('FuelCost') dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( lambda x: x in reactorIds)] - dfFuelCosts = dfFuelCosts.groupby('Time').sum() + dfFuelCosts = dfFuelCosts.groupby('AgentId').sum() costs['Fuel'] = dfFuelCosts.loc[:, 'Payment'] costs = costs.fillna(0) costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear if truncate: endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear costs = costs[costs['Year'].apply(lambda x: x <= endYear)] - beginYear = (simulationBegin + initialMonth - 1) // 12 + initialYear + beginYear = (simulationBegin + initialMon/th - 1) // 12 + initialYear costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] if not capital: del costs['Capital'] + print(costs) costs = costs.groupby('Year').sum() return costs @@ -834,14 +849,14 @@ def region_annual_costs(outputDb, regionId, capital=True, truncate=True): """ db = dbopen(outputDb) evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() + dfInfo = evaler.eval('Info') duration = dfInfo.loc[0, 'Duration'] initialYear = dfInfo.loc[0, 'InitialYear'] initialMonth = dfInfo.loc[0, 'InitialMonth'] dfEcoInfo = evaler.eval('EconomicInfo') simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() + dfEntry = evaler.eval('AgentEntry') tmp = dfEntry[dfEntry.ParentId == regionId] dfEntry = dfEntry[dfEntry['EnterTime'].apply( lambda x: x > simulationBegin and x < simulationEnd)] @@ -867,7 +882,7 @@ def region_annual_costs(outputDb, regionId, capital=True, truncate=True): dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( lambda x: x in reactorIds)] dfOMCosts = dfOMCosts.groupby('Time').sum() - costs['OandM'] = dfOMCosts['Payment'] + costs['OperationAndMaintenance'] = dfOMCosts['Payment'] dfFuelCosts = evaler.eval('FuelCost').reset_index() dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( lambda x: x in reactorIds)] @@ -1173,7 +1188,7 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( lambda x: x in reactorIds)] dfOMCosts = dfOMCosts.groupby('Time').sum() - costs['OandM'] = dfOMCosts['Payment'] + costs['OperationAndMaintenance'] = dfOMCosts['Payment'] dfFuelCosts = evaler.eval('FuelCost').reset_index() dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( lambda x: x in reactorIds)] @@ -1427,6 +1442,5 @@ def simulation_average_lcoe(outputDb): decommissioning + 1))) rtn['Power'] += rtn['Temp2'].fillna(0) - print(id) # test rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 80395497..1656c6e8 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -199,7 +199,8 @@ def build_eco_prot(proto_dict): def get_filiation_per_name(name, dfEntry): filiation = [] filiation.append(name) - parent_id = dfEntry[dfEntry["Prototype"] == name]["ParentId"][0] + parent_id = dfEntry[dfEntry["Prototype"] == name].reset_index()[ + "ParentId"][0] while parent_id != -1: # get the parent @@ -212,7 +213,7 @@ def get_filiation_per_name(name, dfEntry): def get_filiation_per_id(id, dfEntry): - name = dfEntry[dfEntry["AgentId"] == id]["Prototype"][0] + name = dfEntry[dfEntry["AgentId"] == id].reset_index()["Prototype"][0] return get_filiation_per_name(name, dfEntry) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index a13ea71a..85307c25 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -225,8 +225,7 @@ def test_operation_maintenance(): ('Prototype', 'O')]))) eco_metrics.eco_data = eco_tools.eco_input_data("parameters.yml") - obs = eco_metrics.operation_maintenance.func(power, ) - + obs = eco_metrics.operation_maintenance.func(power, entry) assert_frame_equal(exp, obs) @@ -422,33 +421,36 @@ def test_annual_costs(): """ # Reactor / Institution level eco_metrics.eco_data = eco_tools.eco_input_data("parameters.yml") - print(eco_metrics.annual_costs('test.sqlite', 15)) - assert_equal( - eco_metrics.annual_costs('test.sqlite', 15).sum(), - eco_metrics.institution_annual_costs('test.sqlite', 16).sum()) - assert_equal( - eco_metrics.annual_costs_present_value('test.sqlite', 13).sum(), - eco_metrics.institution_annual_costs_present_value('test.sqlite', - 9).sum().sum()) - # Region / Institution level - assert_equal( - eco_metrics.region_annual_costs('test.sqlite', 8).sum().sum(), - eco_metrics.institution_annual_costs('test.sqlite', - 9).sum().sum()) - assert_equal( - eco_metrics.region_annual_costs_present_value( - 'test.sqlite', 8).sum().sum(), - eco_metrics.institution_annual_costs_present_value( - 'test.sqlite', 9).sum().sum()) - # Simulation / Reactor level - assert_equal( - eco_metrics.region_annual_costs('test.sqlite', 8).sum(), - eco_metrics.simulation_annual_costs('test.sqlite').sum().sum()) - assert_equal( - eco_metrics.region_annual_costs_present_value('test.sqlite', - 8).sum().sum(), - eco_metrics.simulation_annual_costs_present_value( - 'test.sqlite').sum().sum()) + obs = eco_metrics.operation_maintenance.func(power, entry) + + print("all", eco_metrics.annual_costs('test.sqlite', 19)) + # print("institution", eco_metrics.institution_annual_costs('test.sqlite', 16)) + # assert_equal( + # eco_metrics.annual_costs('test.sqlite', 15).sum(), + # eco_metrics.institution_annual_costs('test.sqlite', 16).sum()) + # assert_equal( + # eco_metrics.annual_costs_present_value('test.sqlite', 13).sum(), + # eco_metrics.institution_annual_costs_present_value('test.sqlite', + # 9).sum().sum()) + # # Region / Institution level + # assert_equal( + # eco_metrics.region_annual_costs('test.sqlite', 8).sum().sum(), + # eco_metrics.institution_annual_costs('test.sqlite', + # 9).sum().sum()) + # assert_equal( + # eco_metrics.region_annual_costs_present_value( + # 'test.sqlite', 8).sum().sum(), + # eco_metrics.institution_annual_costs_present_value( + # 'test.sqlite', 9).sum().sum()) + # # Simulation / Reactor level + # assert_equal( + # eco_metrics.region_annual_costs('test.sqlite', 8).sum(), + # eco_metrics.simulation_annual_costs('test.sqlite').sum().sum()) + # assert_equal( + # eco_metrics.region_annual_costs_present_value('test.sqlite', + # 8).sum().sum(), + # eco_metrics.simulation_annual_costs_present_value( + # 'test.sqlite').sum().sum()) def test_lcoe(): From 0812b94ee3d221e2399f59b5cbe19ce91838a2d7 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Wed, 3 Jun 2020 17:04:12 -0500 Subject: [PATCH 52/64] working annual cost test --- cymetric/eco_metrics.py | 16 ++++--- tests/test_eco_metrics.py | 96 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 13 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 3c7ee580..368b2174 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -304,20 +304,18 @@ def operation_maintenance(dfPower, dfEntry): @metric(name='MonthlyCosts', depends=_omdeps, schema=_omschema) -def facility_annual_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): +def new_annual_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): """Input : sqlite output database and reactor's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactor is supposed to have been built before the beginning of the simulation. Output : total reactor costs per year over its lifetime. """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) base_col = ['SimId', 'AgentId', 'Time'] costs = pd.DataFrame(columns=base_col) costs_pairs = [(dfCapitalCost, "Capital"), - (dfDecom, "Decommision"), + (dfDecom, "Decommission"), (dfOM, "OperationMaintenance"), (dfFuelCost, "Fuel")] for pair in costs_pairs: @@ -336,9 +334,15 @@ def facility_annual_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): # del costs['Capital'] # costs = costs.groupby(['Year', "AgentId"]).sum().reset_index() # costs.drop(['Time'], axis=1, inplace=True) + return costs.drop(['TransactionId'], axis=1) - print(costs.drop(['SimId'], axis=1)) - return costs + +del _omdeps, _omschema + + +def annual_costs(outputDb, reactorId, capital=True): + cost = pd.DataFrame() + return cost def annual_costs_present_value(outputDb, reactorId, capital=True): diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 85307c25..2262d497 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -20,10 +20,10 @@ def test_capital_cost(): [(UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 0, 0.126000), (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 1, 0.139965), (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 2, 0.112035), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 3, 0.084000), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 4, 0.055965), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 5, 0.028035), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 6, 0.0)], + (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 3, 0.84000), + (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 4, 0.55965), + (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 5, 0.28035), + (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 6, 0.)], dtype=ensure_dt_bytes( [('SimId', 'O'), ('AgentId', ' Date: Mon, 8 Jun 2020 17:16:13 -0500 Subject: [PATCH 53/64] various annual cost working and tested --- cymetric/eco_metrics.py | 286 ++++++++++++++++---------------------- tests/test_eco_metrics.py | 74 +++++----- 2 files changed, 156 insertions(+), 204 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 368b2174..2a3522d7 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -294,22 +294,21 @@ def operation_maintenance(dfPower, dfEntry): ####################################### -_omdeps = ['AgentEntry', 'CapitalCost', - 'DecommissioningCost', 'OperationMaintenance', 'FuelCost'] +_omdeps = ['CapitalCost', + 'DecommissioningCost', + 'OperationMaintenance', + 'FuelCost'] _omschema = [('SimId', ts.UUID), ('AgentId', ts.INT), - ('Time', ts.INT), - ('Payment', ts.DOUBLE)] + ('Fuel', ts.DOUBLE), + ('OperationMaintenance', ts.DOUBLE), + ('Decommission', ts.DOUBLE), + ('Capital', ts.DOUBLE)] @metric(name='MonthlyCosts', depends=_omdeps, schema=_omschema) -def new_annual_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): - """Input : sqlite output database and reactor's AgentId. It is possible not - to take into account the construction costs (capital=False) if the reactor - is supposed to have been built before the beginning of the simulation. - Output : total reactor costs per year over its lifetime. - """ +def montly_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): base_col = ['SimId', 'AgentId', 'Time'] costs = pd.DataFrame(columns=base_col) @@ -329,23 +328,119 @@ def new_annual_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): costs[pair[1]] = 0 costs = costs.fillna(0) - # costs['Year'] = (costs['Time'] + initialMonth - 1) // 12 + initialYear - # if not capital: - # del costs['Capital'] - # costs = costs.groupby(['Year', "AgentId"]).sum().reset_index() - # costs.drop(['Time'], axis=1, inplace=True) return costs.drop(['TransactionId'], axis=1) del _omdeps, _omschema -def annual_costs(outputDb, reactorId, capital=True): - cost = pd.DataFrame() - return cost +def direct_annual_costs(evaler, agents=(), agentsId=(), capital=True): + """Input : sqlite output database and reactor's AgentId. It is possible not + to take into account the construction costs (capital=False) if the reactor + is supposed to have been built before the beginning of the simulation. + Output : total reactor costs per year over its lifetime. + """ + + costs = evaler.eval('MonthlyCosts') + + if len(agents) != 0: + dfAgents = evaler.eval('AgentEntry') + agentsId += dfAgents[dfAgents['Prototype'].isin( + agents)]["AgentId"].tolist() + + if len(agentsId) != 0: + costs = costs[costs['AgentId'].isin(agentsId)] + + dfInfo = evaler.eval('Info') + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + + costs['Year'] = (costs['Time'] + initialMonth - 1) // 12 + initialYear + costs = costs.groupby(['Year', "AgentId"]).sum().reset_index() + costs.drop(['Time'], axis=1, inplace=True) + + if not capital: + del costs['Capital'] + + return costs + + +def child_annual_costs(evaler, agents=(), agentsId=(), capital=True): + """Input : evaler database and institution's AgentId. It is + possible not to take into account the construction costs (capital=False) + if the reactors are supposed to have been built before the beginning of + the simulation. It is also possible to truncate the simulation results and + only have access to cash flows occurring between the two dates (begin and + end) specified in 'parameters.xml'. The truncation allows to let reactors + decommission after the end of the simulation and thus print take into account + cash flows that occur after the end of the simulation for example to + calculate the LCOE. + Output : total reactor costs per year over its lifetime at the institution + level. + """ + + dfEntry = evaler.eval('AgentEntry') + + if len(agents) != 0: + agentsId += dfEntry[dfEntry['Prototype'].isin( + agents)]["AgentId"].tolist() + + childId = [] + while (childId != list(set(dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list()))): + if len(agentsId) != 0: + childId += dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + childId = (list(set(childId))) + agentsId += childId + + costs = direct_annual_costs(evaler, agentsId=childId) + + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum().reset_index() + return costs -def annual_costs_present_value(outputDb, reactorId, capital=True): +def all_annual_costs(evaler, agents=(), agentsId=(), capital=True): + """Input : evaler database and region's AgentId. It is possible not + to take into account the construction costs (capital=False) if the reactors + are supposed to have been built before the beginning of the simulation. It + is also possible to truncate the simulation results and only have access + to cash flows occurring between the two dates (begin and end) specified in + 'parameters.xml'. The truncation allows to let reactors decommission after + the end of the simulation and thus to take into account cash flows that + occur after the end of the simulation for example to calculate the LCOE. + + Output : total reactor costs per year over its lifetime at the region + level. + """ + + dfEntry = evaler.eval('AgentEntry') + + if len(agents) != 0: + agentsId += dfEntry[dfEntry['Prototype'].isin( + agents)]["AgentId"].tolist() + + facilitiesId = agentsId + while (facilitiesId != list(set(dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + agentsId))): + if len(agentsId) != 0: + facilitiesId += dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + facilitiesId = list(set(facilitiesId)) + agentsId += facilitiesId + + costs = direct_annual_costs(evaler, agentsId=facilitiesId) + + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum().reset_index() + return costs + + +def annual_costs_present_value(outputDb, reactorId=(), capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ @@ -398,7 +493,7 @@ def lcoe(outputDb, reactorId, capital=True): powerGenerated = power_generated(outputDb, reactorId) actualization = actualization_vector(powerGenerated.size, discountRate) actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() /\ + return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ ((powerGenerated * actualization).fillna(0).sum()) @@ -522,79 +617,6 @@ def power_generated(outputDb, reactorId): # Institution level -def institution_annual_costs( - outputDb, institutionId, capital=True, truncate=True): - """Input : sqlite output database and institution's AgentId. It is - possible not to take into account the construction costs (capital=False) - if the reactors are supposed to have been built before the beginning of - the simulation. It is also possible to truncate the simulation results and - only have access to cash flows occurring between the two dates (begin and - end) specified in 'parameters.xml'. The truncation allows to let reactors - decommission after the end of the simulation and thus print take into account - cash flows that occur after the end of the simulation for example to - calculate the LCOE. - Output : total reactor costs per year over its lifetime at the institution - level. - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info') - duration = dfInfo['Duration'].iloc[0] - initialYear = dfInfo['InitialYear'].iloc[0] - initialMonth = dfInfo['InitialMonth'].iloc[0] - dfEcoInfo = eco_data.get_prototypes_eco() - simulationBegin = eco_data.dict["eco_model"]["periode"]["start"] - simulationEnd = eco_data.dict["eco_model"]["periode"]["end"] - dfEntry = evaler.eval('AgentEntry') - dfEntry = dfEntry[dfEntry.ParentId == institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - print(dfEntry) - dfPower = evaler.eval('TimeSeriesPower') - reactorIds = dfEntry[dfEntry['AgentId'].apply( - lambda x: isreactor(dfPower, x))]['AgentId'].tolist() - dfCapitalCosts = evaler.eval('CapitalCost') - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( - lambda x: x in reactorIds)] - print(dfCapitalCosts) - dfCapitalCosts = dfCapitalCosts.groupby( - ['AgentId', 'Time']).sum().reset_index() - print(dfCapitalCosts) - - costs = pd.DataFrame( - {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) - print(costs) - dfDecommissioningCosts = evaler.eval('DecommissioningCost') - if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[ - dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] - dfDecommissioningCosts = dfDecommissioningCosts.groupby( - 'AgentId').sum() - costs['Decommissioning'] = dfDecommissioningCosts['Payment'] - dfOMCosts = evaler.eval('OperationMaintenance') - dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfOMCosts = dfOMCosts.groupby('AgentId').sum() - costs['OperationAndMaintenance'] = dfOMCosts.loc[:, 'Payment'] - dfFuelCosts = evaler.eval('FuelCost') - dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfFuelCosts = dfFuelCosts.groupby('AgentId').sum() - costs['Fuel'] = dfFuelCosts.loc[:, 'Payment'] - costs = costs.fillna(0) - costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear - if truncate: - endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x: x <= endYear)] - beginYear = (simulationBegin + initialMon/th - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] - if not capital: - del costs['Capital'] - print(costs) - costs = costs.groupby('Year').sum() - return costs - - def institution_annual_costs_present_value(outputDb, reactorId, capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION @@ -646,10 +668,7 @@ def institution_period_costs( index=list( range( initialYear, - initialYear + - duration // - 12 + - 1))) + initialYear + duration // 12 + 1))) df['Power'] = power df['Costs'] = costs df = df.fillna(0) @@ -827,10 +846,8 @@ def institution_average_lcoe(outputDb, institutionId): rtn['Temp2'] = pd.Series( power, index=list( - range( - commissioning, - decommissioning + - 1))).fillna(0) + range(commissioning, + decommissioning + 1))).fillna(0) rtn['Power'] += rtn['Temp2'].fillna(0) rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] return rtn.fillna(0) @@ -838,73 +855,6 @@ def institution_average_lcoe(outputDb, institutionId): # Region level -def region_annual_costs(outputDb, regionId, capital=True, truncate=True): - """Input : sqlite output database and region's AgentId. It is possible not - to take into account the construction costs (capital=False) if the reactors - are supposed to have been built before the beginning of the simulation. It - is also possible to truncate the simulation results and only have access - to cash flows occurring between the two dates (begin and end) specified in - 'parameters.xml'. The truncation allows to let reactors decommission after - the end of the simulation and thus to take into account cash flows that - occur after the end of the simulation for example to calculate the LCOE. - - Output : total reactor costs per year over its lifetime at the region - level. - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info') - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry') - tmp = dfEntry[dfEntry.ParentId == regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - institutionIds = tmp[tmp.Kind == 'Inst']['AgentId'].tolist() - reactorIds = [] - for id in institutionIds: - dfEntry2 = dfEntry[dfEntry.ParentId == id] - reactorIds += dfEntry2[dfEntry2['Spec'].apply( - lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - dfCapitalCosts = evaler.eval('CapitalCost').reset_index() - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame( - {'Capital': dfCapitalCosts['Payment']}, index=list(range(duration))) - dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() - if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[ - dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] - dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() - costs['Decommissioning'] = dfDecommissioningCosts['Payment'] - dfOMCosts = evaler.eval('OperationMaintenance').reset_index() - dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfOMCosts = dfOMCosts.groupby('Time').sum() - costs['OperationAndMaintenance'] = dfOMCosts['Payment'] - dfFuelCosts = evaler.eval('FuelCost').reset_index() - dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfFuelCosts = dfFuelCosts.groupby('Time').sum() - costs['Fuel'] = dfFuelCosts['Payment'] - costs = costs.fillna(0) - costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear - if truncate: - endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x: x <= endYear)] - beginYear = (simulationBegin + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum() - return costs - - def region_annual_costs_present_value( outputDb, regionId, capital=True, truncate=True): """Same as annual_cost except all values are actualized to the begin date diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 2262d497..bac2a5a2 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -9,8 +9,10 @@ import numpy as np import pandas as pd -from pandas.util.testing import assert_frame_equal +from pandas.util.testing import assert_frame_equal, assert_series_equal +from tools import setup, dbtest +import cymetric as cym from cymetric import eco_metrics, eco_tools from cymetric.tools import raw_to_series, ensure_dt_bytes @@ -416,7 +418,7 @@ def test_yaml_parsing(): assert_equal(obs, exp) -def test_facilities_annual_costs(): +def test_monthly_costs(): decom_cost = pd.DataFrame(np.array( [(UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 0., 11), @@ -464,7 +466,7 @@ def test_facilities_annual_costs(): ('Time', ' Date: Tue, 9 Jun 2020 17:55:29 -0500 Subject: [PATCH 54/64] adding actualized costs --- cymetric/eco_metrics.py | 173 +++++++++++++++++++++++++++++--------- cymetric/eco_tools.py | 8 +- tests/test_eco_metrics.py | 83 +++++++++++++++++- 3 files changed, 217 insertions(+), 47 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 2a3522d7..d6fcfbc6 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -18,14 +18,14 @@ from cymetric.metrics import metric from cymetric.tools import dbopen, merge from cymetric.evaluator import Evaluator - from cymetric.eco_tools import actualization_vector, isreactor, \ + from cymetric.eco_tools import actualize, actualization_vector, isreactor, \ capital_shape, get_filiation_per_id, eco_input_data from cymetric.evaluator import register_metric except ImportError: # some wacky CI paths prevent absolute importing, try relative from .metrics import metric from .evaluator import register_metric - from .eco_tools import capital_shape, isreactor, actualization_vector, \ + from .eco_tools import actualize, capital_shape, isreactor, actualization_vector, \ isreactor, get_filiation_per_id, eco_input_data from .tools import dbopen, merge from .evaluator import Evaluator @@ -300,6 +300,7 @@ def operation_maintenance(dfPower, dfEntry): 'FuelCost'] _omschema = [('SimId', ts.UUID), + ('Time', ts.INT), ('AgentId', ts.INT), ('Fuel', ts.DOUBLE), ('OperationMaintenance', ts.DOUBLE), @@ -347,7 +348,6 @@ def direct_annual_costs(evaler, agents=(), agentsId=(), capital=True): dfAgents = evaler.eval('AgentEntry') agentsId += dfAgents[dfAgents['Prototype'].isin( agents)]["AgentId"].tolist() - if len(agentsId) != 0: costs = costs[costs['AgentId'].isin(agentsId)] @@ -440,14 +440,138 @@ def all_annual_costs(evaler, agents=(), agentsId=(), capital=True): return costs -def annual_costs_present_value(outputDb, reactorId=(), capital=True): +def actualize_costs(df, columns, time_col='Time', time_factor=12.): + discount_rate = eco_data.dict['finance']['discount_rate'] + df_actualised = df.copy(deep=True) + + for index, row in df_actualised.iterrows(): + t = row[time_col] / time_factor + actualization = actualize(t, discount_rate) + + for col in columns: + df_actualised.at[index, col] *= actualization + return df_actualised + + +_omdeps = ['MonthlyCosts', ] + +_omschema = [('SimId', ts.UUID), + ('AgentId', ts.INT), + ('Fuel', ts.DOUBLE), + ('OperationMaintenance', ts.DOUBLE), + ('Decommission', ts.DOUBLE), + ('Capital', ts.DOUBLE)] + + +@metric(name='ActualizedMonthlyCosts', depends=_omdeps, schema=_omschema) +def actualised_montly_costs(dfMontlyCost): + + df_actualised = dfMontlyCost.copy(deep=True) + + col_to_actualize = ['Fuel', + 'OperationMaintenance', + 'Decommission', + 'Capital'] + return actualize_costs(df_actualised, col_to_actualize, time_col='Time', time_factor=12.) + + +del _omdeps, _omschema + + +def direct_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - costs = annual_costs(outputDb, reactorId, capital) - actualization = actualization_vector(len(costs)) - actualization.index = costs.index - return costs.apply(lambda x: x * actualization) + + costs = evaler.eval('ActualizedMonthlyCosts') + + if len(agents) != 0: + dfAgents = evaler.eval('AgentEntry') + agentsId += dfAgents[dfAgents['Prototype'].isin( + agents)]["AgentId"].tolist() + if len(agentsId) != 0: + costs = costs[costs['AgentId'].isin(agentsId)] + + dfInfo = evaler.eval('Info') + duration = dfInfo.loc[0, 'Duration'] + initialYear = dfInfo.loc[0, 'InitialYear'] + initialMonth = dfInfo.loc[0, 'InitialMonth'] + + costs['Year'] = (costs['Time'] + initialMonth - 1) // 12 + initialYear + costs = costs.groupby(['Year', "AgentId"]).sum().reset_index() + costs.drop(['Time'], axis=1, inplace=True) + + if not capital: + del costs['Capital'] + + return costs + + +def child_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + + dfEntry = evaler.eval('AgentEntry') + + if len(agents) != 0: + agentsId += dfEntry[dfEntry['Prototype'].isin( + agents)]["AgentId"].tolist() + + childId = [] + while (childId != list(set(dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list()))): + if len(agentsId) != 0: + childId += dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + childId = (list(set(childId))) + agentsId += childId + + costs = direct_actualized_annual_costs(evaler, agentsId=childId) + + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum().reset_index() + costs['AgentId'] = -1 + return costs + + +def all_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + + dfEntry = evaler.eval('AgentEntry') + + if len(agents) != 0: + agentsId += dfEntry[dfEntry['Prototype'].isin( + agents)]["AgentId"].tolist() + + facilitiesId = agentsId + if len(agentsId) != 0: + while (facilitiesId != list(set(dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + agentsId))): + if len(agentsId) != 0: + facilitiesId += dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + facilitiesId = list(set(facilitiesId)) + agentsId += facilitiesId + + costs = direct_actualized_annual_costs(evaler, agentsId=facilitiesId) + + if not capital: + del costs['Capital'] + costs = costs.groupby('Year').sum().reset_index() + costs['AgentId'] = -1 + + return costs + + +def simulation_actualized_annual_costs(outputDb, capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + return all_actualized_annual_costs(outputDb, capital=capital) def average_cost(outputDb, reactorId, capital=True): @@ -617,16 +741,6 @@ def power_generated(outputDb, reactorId): # Institution level -def institution_annual_costs_present_value(outputDb, reactorId, capital=True): - """Same as annual_cost except all values are actualized to the begin date - of the SIMULATION - """ - costs = institution_annual_costs(outputDb, institutionId, capital) - actualization = actualization_vector(len(costs)) - actualization.index = costs.index - return costs.apply(lambda x: x * actualization) - - def institution_benefit(outputDb, institutionId): """Input : sqlite output database and institution agent id Output : cumulative sum of income and expense (= - expenditures + income) @@ -855,17 +969,6 @@ def institution_average_lcoe(outputDb, institutionId): # Region level -def region_annual_costs_present_value( - outputDb, regionId, capital=True, truncate=True): - """Same as annual_cost except all values are actualized to the begin date - of the SIMULATION - """ - costs = region_annual_costs(outputDb, regionId, capital) - actualization = actualization_vector(len(costs)) - actualization.index = costs.index - return costs.apply(lambda x: x * actualization) - - def region_benefit(outputDb, regionId): """Input : sqlite output database and region agent id Output : cumulative sum of actualized income and expense @@ -1161,18 +1264,6 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): return costs -def simulation_annual_costs_present_value( - outputDb, capital=True, truncate=True): - """Same as annual_cost except all values are actualized to the begin date - of the SIMULATION - """ - df = simulation_annual_costs(outputDb, capital, truncate) - for year in df.index: - df.loc[year, :] = df.loc[year, :] / \ - (1 + default_discount_rate) ** (year - df.index[0]) - return df - - def simulation_benefit(outputDb): """Input : sqlite output database Output : cumulative sum of total income and total expense diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 1656c6e8..353c12d4 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -40,13 +40,13 @@ def __init__(self, filename): def load_economic_info(self, eco_input): stream = open(eco_input) data = yaml.load(stream, Loader=yaml.FullLoader) - self.dict = data + self.dict = data["eco_model"] def get_prototype_eco(self, filiation): """ Return a dict with all the colapsed properties of a prototype """ proto_eco = {} - traveling_dict = self.dict["eco_model"] + traveling_dict = self.dict for prop in eco_properties: if prop in traveling_dict: proto_eco[prop] = traveling_dict[prop] @@ -80,7 +80,7 @@ def get_prototypes_eco(self): df_eco = pd.DataFrame(columns=row_col) proto_eco = {} - model_dict = self.dict["eco_model"] + model_dict = self.dict # Set default eco data for prop in eco_properties: @@ -399,7 +399,7 @@ def actualization_vector(size, discountRate): return rtn * (1 + discountRate) -def actualize(price, delta_t, discount_rate): +def actualize(delta_t, discount_rate, price=1.): """Given a price at date t + delta_t, give the actualized price at t. """ return price / (1 + discount_rate) ** delta_t diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index bac2a5a2..76c3373b 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -500,6 +500,81 @@ def test_monthly_costs(): assert_frame_equal(obs, exp) +def test_actualized_monthly_costs(): + + monthly_cost = pd.DataFrame(np.array( + [(UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 12, 1, 1.0, 0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 12, 2, 1.0, 0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 12, 8, 1.0, 0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 12, 9, 1.0, 0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 1, 0, 1095.0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 2, 0, 1095.0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 3, 0, 1095.0, 0, 0.84), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 8, 0, 1095.0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 9, 0, 1095.0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 11, 0, 0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 12, 0, 0, 0.133333, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 13, 0, 0, 0.266667, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 16, 0, 0, 0, 0), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 0, 0, 0, 0, 0.126), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 4, 0, 0, 0, 0.55965), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 5, 0, 0, 0, 0.28035), + (UUID('0ac0f445-3e1c-43ec-826c-8702d4fc2f40'), 13, 6, 0, 0, 0, 0)], + dtype=ensure_dt_bytes( + [('SimId', 'O'), + ('AgentId', ' Date: Wed, 10 Jun 2020 11:58:54 -0500 Subject: [PATCH 55/64] average cost --- cymetric/eco_metrics.py | 17 +++++++++-------- tests/test_eco_metrics.py | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index d6fcfbc6..2e97633d 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -574,18 +574,19 @@ def simulation_actualized_annual_costs(outputDb, capital=True): return all_actualized_annual_costs(outputDb, capital=capital) -def average_cost(outputDb, reactorId, capital=True): - """Input : sqlite output database, reactor's AgentId +def average_cost(evaler, reactorId, capital=True): + """Input : evaler, reactor's AgentId Output : value (in $/MWh) corresponding to the total costs (sum of annual costs) divided by the total power generated. """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) + dfPower = evaler.eval('TimeSeriesPower').reset_index() - powerGenerated = sum( - dfPower[dfPower.AgentId == reactorId].loc[:, 'Value']) * 8760 / 12 - return annual_costs(outputDb, reactorId, - capital).sum().sum() / powerGenerated + powerGenerated = dfPower[dfPower.AgentId == + reactorId].loc[:, 'Value'].sum() / 12. * 365.25 * 24 + print(powerGenerated) + return direct_actualized_annual_costs( + evaler, agentsId=[reactorId], capital=capital).drop(['Year', + 'AgentId'], axis=1).sum().sum() / powerGenerated def benefit(outputDb, reactorId): diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 76c3373b..79a3a41d 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -599,6 +599,7 @@ def test_annual_costs(db, fname, backend): print(eco_metrics.direct_actualized_annual_costs(evaler, agentsId=[17, 18, 19, 20, 21])) print(eco_metrics.simulation_actualized_annual_costs(evaler)) + print(eco_metrics.average_cost(evaler, 19)) # assert_equal( # eco_metrics.region_annual_costs_present_value( From c09af949dd53b453522ecdf2ae22c270fd2a1963 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 11 Jun 2020 20:28:55 -0500 Subject: [PATCH 56/64] some progress --- cymetric/eco_metrics.py | 274 +++++++++++++++++--------------------- cymetric/eco_tools.py | 21 ++- cymetric/metrics.py | 24 ++-- tests/test_eco_metrics.py | 53 ++++---- 4 files changed, 172 insertions(+), 200 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 2e97633d..4e570bd4 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -18,15 +18,13 @@ from cymetric.metrics import metric from cymetric.tools import dbopen, merge from cymetric.evaluator import Evaluator - from cymetric.eco_tools import actualize, actualization_vector, isreactor, \ - capital_shape, get_filiation_per_id, eco_input_data + from cymetric import eco_tools from cymetric.evaluator import register_metric except ImportError: # some wacky CI paths prevent absolute importing, try relative from .metrics import metric from .evaluator import register_metric - from .eco_tools import actualize, capital_shape, isreactor, actualization_vector, \ - isreactor, get_filiation_per_id, eco_input_data + from . import eco_tools from .tools import dbopen, merge from .evaluator import Evaluator @@ -63,7 +61,7 @@ def capital_cost(dfPower, dfEntry, dfInfo): rtn = pd.DataFrame() for index, power_row in dfPower.iterrows(): agent_id = power_row['AgentId'] - filiation = get_filiation_per_id(agent_id, dfEntry) + filiation = eco_tools.get_filiation_per_id(agent_id, dfEntry) agent_eco_prop = eco_data.get_prototype_eco(filiation) deviation = float(agent_eco_prop["capital"]["deviation"]) @@ -72,7 +70,7 @@ def capital_cost(dfPower, dfEntry, dfInfo): beforePeak = int(agent_eco_prop["capital"]["beforePeak"]) + deviation afterPeak = int(agent_eco_prop["capital"]["afterPeak"]) - cashFlowShape = capital_shape(beforePeak, afterPeak) + cashFlowShape = eco_tools.capital_shape(beforePeak, afterPeak) constructionDuration = int( agent_eco_prop["capital"]['constructionDuration']) + deviation @@ -257,33 +255,6 @@ def operation_maintenance(dfPower, dfEntry): del _omdeps, _omschema -_eideps = ['AgentEntry'] - -_eischema = [('Prototype', ts.STRING), - ('AgentId', ts.INT), - ('ParentId', ts.INT), - ('ReturnOnDebt', ts.DOUBLE), - ('ReturnOnEquity', ts.DOUBLE), - ('TaxRate', ts.DOUBLE), - ('DiscountRate', ts.DOUBLE), - ('beforePeak', ts.INT), - ('afterPeak', ts.INT), - ('constructionDuration', ts.INT), - ('Capital_Deviation', ts.DOUBLE), - ('OvernightCost', ts.DOUBLE), - ('Duration', ts.INT), - ('OvernightCost', ts.DOUBLE), - ('FixedCost', ts.DOUBLE), - ('VariableCost', ts.DOUBLE), - ('OperationMaintenance_Deviation', ts.DOUBLE), - ('FuelCommodity', ts.STRING), - ('SupplyCost', ts.DOUBLE), - ('WasteFee', ts.DOUBLE), - ('Fuel_Deviation', ts.DOUBLE), - ('Truncation_Begin', ts.INT), - ('Truncation_End', ts.INT)] - - """The functions below aim at calculating more complex metrics than the simple cash flows corresponding to the construction, fuel, O&M and decommissioning costs. The metrics can be calculated at an agent, institution, region or @@ -335,7 +306,7 @@ def montly_costs(dfCapitalCost, dfDecom, dfOM, dfFuelCost): del _omdeps, _omschema -def direct_annual_costs(evaler, agents=(), agentsId=(), capital=True): +def annual_costs(evaler, agents=(), agentsId=(), capital=True): """Input : sqlite output database and reactor's AgentId. It is possible not to take into account the construction costs (capital=False) if the reactor is supposed to have been built before the beginning of the simulation. @@ -386,16 +357,9 @@ def child_annual_costs(evaler, agents=(), agentsId=(), capital=True): agentsId += dfEntry[dfEntry['Prototype'].isin( agents)]["AgentId"].tolist() - childId = [] - while (childId != list(set(dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list()))): - if len(agentsId) != 0: - childId += dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list() - childId = (list(set(childId))) - agentsId += childId + childId = eco_tools.get_child_id(agentsId, dfEntry) - costs = direct_annual_costs(evaler, agentsId=childId) + costs = annual_costs(evaler, agentsId=childId) if not capital: del costs['Capital'] @@ -423,16 +387,8 @@ def all_annual_costs(evaler, agents=(), agentsId=(), capital=True): agentsId += dfEntry[dfEntry['Prototype'].isin( agents)]["AgentId"].tolist() - facilitiesId = agentsId - while (facilitiesId != list(set(dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list() + agentsId))): - if len(agentsId) != 0: - facilitiesId += dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list() - facilitiesId = list(set(facilitiesId)) - agentsId += facilitiesId - - costs = direct_annual_costs(evaler, agentsId=facilitiesId) + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + costs = annual_costs(evaler, agentsId=agentsId) if not capital: del costs['Capital'] @@ -440,20 +396,22 @@ def all_annual_costs(evaler, agents=(), agentsId=(), capital=True): return costs -def actualize_costs(df, columns, time_col='Time', time_factor=12.): - discount_rate = eco_data.dict['finance']['discount_rate'] - df_actualised = df.copy(deep=True) +def actualize_costs(df, columns, dfEntry, time_col='Time', time_factor=12., t_0=0): + df_actualised = df.copy() for index, row in df_actualised.iterrows(): + agent_eco = eco_data.get_prototype_eco( + eco_tools.get_filiation_per_id(row['AgentId'], dfEntry)) + discount_rate = agent_eco['finance']['discount_rate'] t = row[time_col] / time_factor - actualization = actualize(t, discount_rate) + actualization = eco_tools.actualize(t-t_0, discount_rate) for col in columns: df_actualised.at[index, col] *= actualization return df_actualised -_omdeps = ['MonthlyCosts', ] +_omdeps = ['MonthlyCosts', 'AgentEntry'] _omschema = [('SimId', ts.UUID), ('AgentId', ts.INT), @@ -463,30 +421,30 @@ def actualize_costs(df, columns, time_col='Time', time_factor=12.): ('Capital', ts.DOUBLE)] -@metric(name='ActualizedMonthlyCosts', depends=_omdeps, schema=_omschema) -def actualised_montly_costs(dfMontlyCost): +@ metric(name='ActualizedMonthlyCosts', depends=_omdeps, schema=_omschema) +def actualised_montly_costs(dfMontlyCost, dfEntry): - df_actualised = dfMontlyCost.copy(deep=True) + df_actualised = dfMontlyCost.copy() col_to_actualize = ['Fuel', 'OperationMaintenance', 'Decommission', 'Capital'] - return actualize_costs(df_actualised, col_to_actualize, time_col='Time', time_factor=12.) + return actualize_costs(df_actualised, col_to_actualize, dfEntry, time_col='Time', time_factor=12.) del _omdeps, _omschema -def direct_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): +def actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - costs = evaler.eval('ActualizedMonthlyCosts') + costs = evaler.eval('ActualizedMonthlyCosts').copy() if len(agents) != 0: - dfAgents = evaler.eval('AgentEntry') + dfAgents = evaler.eval('AgentEntry').copy() agentsId += dfAgents[dfAgents['Prototype'].isin( agents)]["AgentId"].tolist() if len(agentsId) != 0: @@ -512,22 +470,15 @@ def child_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): of the SIMULATION """ - dfEntry = evaler.eval('AgentEntry') + dfEntry = evaler.eval('AgentEntry').copy() if len(agents) != 0: agentsId += dfEntry[dfEntry['Prototype'].isin( agents)]["AgentId"].tolist() - childId = [] - while (childId != list(set(dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list()))): - if len(agentsId) != 0: - childId += dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list() - childId = (list(set(childId))) - agentsId += childId + childId = eco_tools.get_child_id(agentsId, dfEntry) - costs = direct_actualized_annual_costs(evaler, agentsId=childId) + costs = actualized_annual_costs(evaler, agentsId=childId) if not capital: del costs['Capital'] @@ -536,28 +487,20 @@ def child_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): return costs -def all_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): +def all_actualized_annual_costs(evaler, agents=[], agentsId=[], capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - dfEntry = evaler.eval('AgentEntry') + dfEntry = evaler.eval('AgentEntry').copy() if len(agents) != 0: agentsId += dfEntry[dfEntry['Prototype'].isin( agents)]["AgentId"].tolist() - facilitiesId = agentsId - if len(agentsId) != 0: - while (facilitiesId != list(set(dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list() + agentsId))): - if len(agentsId) != 0: - facilitiesId += dfEntry[dfEntry['ParentId'].isin( - agentsId)]['AgentId'].to_list() - facilitiesId = list(set(facilitiesId)) - agentsId += facilitiesId + agentsId += eco_tools.get_child_id(agentsId, dfEntry) - costs = direct_actualized_annual_costs(evaler, agentsId=facilitiesId) + costs = actualized_annual_costs(evaler, agentsId=agentsId) if not capital: del costs['Capital'] @@ -580,46 +523,104 @@ def average_cost(evaler, reactorId, capital=True): costs) divided by the total power generated. """ - dfPower = evaler.eval('TimeSeriesPower').reset_index() - powerGenerated = dfPower[dfPower.AgentId == - reactorId].loc[:, 'Value'].sum() / 12. * 365.25 * 24 - print(powerGenerated) - return direct_actualized_annual_costs( - evaler, agentsId=[reactorId], capital=capital).drop(['Year', - 'AgentId'], axis=1).sum().sum() / powerGenerated + powerGenerated = power_generated(evaler, [reactorId])['Energy'].sum() + costs = actualized_annual_costs(evaler, + agentsId=[reactorId], + capital=capital) + # removing Year and AgentId column (for the sum) + costs.drop(['Year', 'AgentId'], axis=1, inplace=True) + + return costs.sum().sum() / powerGenerated + +def power_generated(evaler, agentsId=[]): + """Input : cymetric evaler and reactor agent id + Output : Electricity generated in MWh every year + """ + dfPower = evaler.eval('AnnualElectricityGeneratedByAgent').copy() + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] -def benefit(outputDb, reactorId): - """Input : sqlite output database and reactor agent id + # Convert to absolute time + dfPower['Year'] = dfPower['Year'] + initialYear + # Convert Power to MWh + dfPower['Energy'] *= 365.25 * 24 + + # Return table filtered by AgentsId + return dfPower[dfPower['AgentId'].isin(agentsId)] + + +def benefit(evaler, reactorId): + """Input : evaler database and reactor agent id Output : cumulative sum of actualized income and expense (= - expenditures + income) """ - costs = - annual_costs(outputDb, reactorId).sum(axis=1) - powerGenerated = power_generated( - outputDb, reactorId) * lcoe(outputDb, reactorId) - rtn = pd.concat([costs, powerGenerated], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn + costs = actualized_annual_costs(evaler=evaler, + agentsId=[reactorId]) + power_income = power_generated(evaler=evaler, + agentsId=[reactorId]) + power_income["Energy"] *= lcoe(evaler=evaler, agentsId=[reactorId]) + + base_col = ['AgentId', 'Year'] + added_col = base_col + ['Fuel', + 'OperationMaintenance', + 'Capital', + 'Decommission'] + power_income = merge(power_income, base_col, costs, added_col) + # I don't get this, basically we do lcoe*power - cost where lcoe = cost/power... + # so benefit are necessary 0 + power_income['Capital'] = power_income['Energy'] - (power_income['Fuel'] + + power_income['OperationMaintenance'] + + power_income['Capital'] + + power_income['Decommission']) + + return power_income[['SimId', 'AgentId', 'Year', 'Capital']] + + +def lcoe(evaler, agentsId=[], capital=True): + """Input : evaler database and reactor agent id + Output : Value corresponding to Levelized Cost of Electricity ($/MWh) + """ + costs = actualized_annual_costs(evaler=evaler, + agentsId=agentsId, + capital=capital).drop(['AgentId', 'Year'], axis=1) + power = power_generated(evaler=evaler, agentsId=agentsId) + + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + dfEntry = evaler.eval('AgentEntry') + actualized_power = actualize_costs(df=power, + columns=["Energy"], + dfEntry=dfEntry, + time_col="Year", + time_factor=1., + t_0=initialYear).drop(['SimId', 'AgentId', 'Year'], axis=1) + + return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() -def lcoe(outputDb, reactorId, capital=True): - """Input : sqlite output database and reactor agent id +def child_lcoe(evaler, agentsId=[], capital=True): + """Input : sqlite output database and institution agent id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfEcoInfo = evaler.eval('EconomicInfo') - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - discountRate = dfEcoInfo.loc[reactorId, ('Finance', 'DiscountRate')] - annualCosts = annual_costs(outputDb, reactorId, capital) - powerGenerated = power_generated(outputDb, reactorId) - actualization = actualization_vector(powerGenerated.size, discountRate) - actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ - ((powerGenerated * actualization).fillna(0).sum()) + costs = child_actualized_annual_costs(evaler=evaler, + agentsId=agentsId, + capital=capital).drop(['AgentId', 'Year'], axis=1) + + dfEntry = evaler.eval('AgentEntry').copy() + + childId = eco_tools.get_child_id(agentsId, dfEntry) + + power = power_generated(evaler=evaler, agentsId=childId) + + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + dfEntry = evaler.eval('AgentEntry') + actualized_power = actualize_costs(df=power, + columns=["Energy"], + dfEntry=dfEntry, + time_col="Year", + time_factor=1., + t_0=initialYear).drop(['SimId', 'AgentId', 'Year'], axis=1) + + return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): @@ -719,26 +720,6 @@ def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): return rtn -def power_generated(outputDb, reactorId): - """Input : sqlite output database and reactor agent id - Output : Electricity generated in MWh every year - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfPower = evaler.eval('TimeSeriesPower').reset_index() - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfPower = dfPower[dfPower['AgentId'] == reactorId].copy() - dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear - dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, - index=list(range(initialYear, - initialYear + (initialMonth + duration) // - 12 + 1))) - return rtn.fillna(0) - # Institution level @@ -894,23 +875,6 @@ def institution_power_generated(outputDb, institutionId, truncate=True): return rtn.fillna(0) -def institution_lcoe(outputDb, institutionId): - """Input : sqlite output database and institution agent id - Output : Value corresponding to Levelized Cost of Electricity ($/MWh) - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfEcoInfo = evaler.eval('EconomicInfo') - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - discountRate = dfEcoInfo.loc[institutionId, ('Finance', 'DiscountRate')] - annualCosts = institution_annual_costs(outputDb, institutionId) - powerGenerated = institution_power_generated(outputDb, institutionId) - actualization = actualization_vector(powerGenerated.size, discountRate) - actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ - ((powerGenerated * actualization).fillna(0).sum()) - - def institution_average_lcoe(outputDb, institutionId): """Input : sqlite output database and institution agent id Output : Variable cost corresponding at each time step (i.e. every year) diff --git a/cymetric/eco_tools.py b/cymetric/eco_tools.py index 353c12d4..088db1ef 100644 --- a/cymetric/eco_tools.py +++ b/cymetric/eco_tools.py @@ -213,13 +213,28 @@ def get_filiation_per_name(name, dfEntry): def get_filiation_per_id(id, dfEntry): + """ + Input : Agents entry table and agents id + Output : list of childs AgentId + """ name = dfEntry[dfEntry["AgentId"] == id].reset_index()["Prototype"][0] return get_filiation_per_name(name, dfEntry) -#################### -# Mining & Milling # -#################### +def get_child_id(agentsId, dfEntry): + childId = [] + while (childId != list(set(dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list()))): + if len(agentsId) != 0: + childId += dfEntry[dfEntry['ParentId'].isin( + agentsId)]['AgentId'].to_list() + childId = (list(set(childId))) + agentsId += childId + return childId + + #################### + # Mining & Milling # + #################### def isuraniumsource(dfEntry, id): diff --git a/cymetric/metrics.py b/cymetric/metrics.py index d3644dd0..26a95632 100644 --- a/cymetric/metrics.py +++ b/cymetric/metrics.py @@ -106,7 +106,7 @@ def dec(f): ('NucId', ts.INT), ('Units', ts.STRING), ('Mass', ts.DOUBLE) - ] +] @metric(name='Materials', depends=_matdeps, schema=_matschema) @@ -138,7 +138,7 @@ def materials(rsrcs, comps): ('TimeCreated', ts.INT), ('NucId', ts.INT), ('Activity', ts.DOUBLE) - ] +] @metric(name='Activity', depends=_actdeps, schema=_actschema) @@ -177,7 +177,7 @@ def activity(mats): ('TimeCreated', ts.INT), ('NucId', ts.INT), ('DecayHeat', ts.DOUBLE) - ] +] @metric(name='DecayHeat', depends=_dhdeps, schema=_dhschema) @@ -210,7 +210,7 @@ def decay_heat(acts): _bsschema = [ ('SimId', ts.UUID), ('EnterTime', ts.INT), ('Prototype', ts.STRING), ('Count', ts.INT) - ] +] @metric(name='BuildSeries', depends=_bsdeps, schema=_bsschema) @@ -235,7 +235,7 @@ def build_series(entry): ('ExitTime', ts.INT), ('Prototype', ts.STRING), ('Count', ts.INT) - ] +] @metric(name='DecommissionSeries', depends=_dsdeps, schema=_dsschema) @@ -270,7 +270,7 @@ def decommission_series(entry, exit): ('Lifetime', ts.INT), ('EnterTime', ts.INT), ('ExitTime', ts.INT), - ]) +]) @metric(name='Agents', depends=_agentsdeps, schema=_agentsschema) @@ -318,7 +318,7 @@ def agents(entry, exit, decom, info): ('Commodity', ts.STRING), ('Units', ts.STRING), ('Quantity', ts.DOUBLE) - ] +] @metric(name='TransactionQuantity', depends=_transdeps, schema=_transschema) @@ -350,7 +350,7 @@ def transaction_quantity(mats, tranacts): ('InventoryName', ts.STRING), ('NucId', ts.INT), ('Quantity', ts.DOUBLE) - ] +] @metric(name='ExplicitInventoryByAgent', depends=_invdeps, schema=_invschema) @@ -381,7 +381,7 @@ def explicit_inventory_by_agent(expinv): ('InventoryName', ts.STRING), ('NucId', ts.INT), ('Quantity', ts.DOUBLE) - ] +] @metric(name='ExplicitInventoryByNuc', depends=_invdeps, schema=_invschema) @@ -411,7 +411,7 @@ def explicit_inventory_by_nuc(expinv): ('AgentId', ts.INT), ('Year', ts.INT), ('Energy', ts.DOUBLE) - ] +] @metric(name='AnnualElectricityGeneratedByAgent', depends=_egdeps, @@ -443,7 +443,7 @@ def annual_electricity_generated_by_agent(elec): ('AgentId', ts.INT), ('Month', ts.INT), ('Energy', ts.DOUBLE) - ] +] @metric(name='MonthlyElectricityGeneratedByAgent', depends=_egdeps, @@ -519,7 +519,7 @@ def inventory_quantity_per_gwe(inv, power): _tlschema = [ ('SimId', ts.UUID), ('TimeStep', ts.INT) - ] +] @metric(name='TimeList', depends=_tldeps, schema=_tlschema) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 79a3a41d..d0574e3e 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -581,8 +581,8 @@ def test_annual_costs(db, fname, backend): # Reactor / Institution level eco_metrics.eco_data = eco_tools.eco_input_data("parameters.yml") - obs_1 = eco_metrics.direct_annual_costs(evaler, - agentsId=[17, 18, 19, 20, 21]) + obs_1 = eco_metrics.annual_costs(evaler, + agentsId=[17, 18, 19, 20, 21]) obs_1.drop(['AgentId', 'Year'], axis=1, inplace=True) obs_2 = eco_metrics.child_annual_costs(evaler, @@ -590,45 +590,38 @@ def test_annual_costs(db, fname, backend): obs_2.drop(['AgentId', 'Year'], axis=1, inplace=True) assert_series_equal(obs_1.sum(), obs_2.sum()) - # Region / Institution level obs_3 = eco_metrics.all_annual_costs(evaler, agentsId=[15]) obs_3.drop(['AgentId', 'Year'], axis=1, inplace=True) assert_series_equal(obs_1.sum(), obs_3.sum()) - print(eco_metrics.direct_actualized_annual_costs(evaler, - agentsId=[17, 18, 19, 20, 21])) print(eco_metrics.simulation_actualized_annual_costs(evaler)) print(eco_metrics.average_cost(evaler, 19)) + print(eco_metrics.benefit(evaler, 19)) + -# assert_equal( -# eco_metrics.region_annual_costs_present_value( -# 'test.sqlite', 8).sum().sum(), -# eco_metrics.institution_annual_costs_present_value( -# 'test.sqlite', 9).sum().sum()) -# # Simulation / Reactor level -# assert_equal( -# eco_metrics.region_annual_costs('test.sqlite', 8).sum(), -# eco_metrics.simulation_annual_costs('test.sqlite').sum().sum()) -# assert_equal( -# eco_metrics.region_annual_costs_present_value('test.sqlite', -# 8).sum().sum(), -# eco_metrics.simulation_annual_costs_present_value( -# 'test.sqlite').sum().sum()) - - -def test_lcoe(): +@dbtest +def test_lcoe(db, fname, backend): """ """ + evaler = cym.Evaluator(db) + eco_metrics.eco_data = eco_tools.eco_input_data("parameters.yml") + # Reactor / Institution level - assert_equal(eco_metrics.lcoe('tests/test.sqlite', 13), - eco_metrics.institution_lcoe('tests/test.sqlite', 9)) - # Region / Institution level - assert_equal(eco_metrics.region_lcoe('tests/test.sqlite', 8), - eco_metrics.institution_lcoe('tests/test.sqlite', 9)) - # Simulation / Reactor level - assert_equal(eco_metrics.region_lcoe('tests/test.sqlite', 8), - eco_metrics.simulation_lcoe('tests/test.sqlite')) + obs_1 = eco_metrics.lcoe(evaler, + agentsId=[17, 18, 19, 20, 21]) + print(obs_1) + obs_2 = eco_metrics.child_lcoe(evaler, + agentsId=[16]) + print(obs_2) + + assert_equal(obs_1, obs_2) + # # Region / Institution level + # assert_equal(eco_metrics.region_lcoe(evaler, 8), + # eco_metrics.institution_lcoe(evaler, 9)) + # # Simulation / Reactor level + # assert_equal(eco_metrics.region_lcoe(evaler, 8), + # eco_metrics.simulation_lcoe(evaler)) def test_average_lcoe(): From 446516a7918da4dff9f01ffa6c4da75c465837dc Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 11 Jun 2020 20:41:52 -0500 Subject: [PATCH 57/64] lcoe working --- cymetric/eco_metrics.py | 41 ++++++++++++++++++++++++++++----------- tests/test_eco_metrics.py | 15 +++++++------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 4e570bd4..bb488f21 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -576,13 +576,12 @@ def benefit(evaler, reactorId): return power_income[['SimId', 'AgentId', 'Year', 'Capital']] -def lcoe(evaler, agentsId=[], capital=True): - """Input : evaler database and reactor agent id +def lcoe(evaler, agentsId=[]): + """Input : evaler database and agents id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) """ costs = actualized_annual_costs(evaler=evaler, - agentsId=agentsId, - capital=capital).drop(['AgentId', 'Year'], axis=1) + agentsId=agentsId).drop(['AgentId', 'Year'], axis=1) power = power_generated(evaler=evaler, agentsId=agentsId) initialYear = evaler.eval('Info').loc[0, 'InitialYear'] @@ -597,18 +596,15 @@ def lcoe(evaler, agentsId=[], capital=True): return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() -def child_lcoe(evaler, agentsId=[], capital=True): - """Input : sqlite output database and institution agent id +def child_lcoe(evaler, agentsId=[]): + """Input : evaler database and Instutions/Region id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) """ - costs = child_actualized_annual_costs(evaler=evaler, - agentsId=agentsId, - capital=capital).drop(['AgentId', 'Year'], axis=1) - dfEntry = evaler.eval('AgentEntry').copy() - childId = eco_tools.get_child_id(agentsId, dfEntry) + costs = child_actualized_annual_costs(evaler=evaler, + agentsId=childId).drop(['AgentId', 'Year'], axis=1) power = power_generated(evaler=evaler, agentsId=childId) initialYear = evaler.eval('Info').loc[0, 'InitialYear'] @@ -623,6 +619,29 @@ def child_lcoe(evaler, agentsId=[], capital=True): return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() +def all_lcoe(evaler, agentsId=[]): + """Input : sqlite output database and Instutions/Region agent id + Output : Value corresponding to Levelized Cost of Electricity ($/MWh) + """ + dfEntry = evaler.eval('AgentEntry').copy() + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + + costs = actualized_annual_costs(evaler=evaler, + agentsId=agentsId).drop(['AgentId', 'Year'], axis=1) + power = power_generated(evaler=evaler, agentsId=agentsId) + + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + dfEntry = evaler.eval('AgentEntry') + actualized_power = actualize_costs(df=power, + columns=["Energy"], + dfEntry=dfEntry, + time_col="Year", + time_factor=1., + t_0=initialYear).drop(['SimId', 'AgentId', 'Year'], axis=1) + + return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() + + def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): """Input : sqlite output database, reactor id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index d0574e3e..15bf4f80 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -595,9 +595,9 @@ def test_annual_costs(db, fname, backend): obs_3.drop(['AgentId', 'Year'], axis=1, inplace=True) assert_series_equal(obs_1.sum(), obs_3.sum()) - print(eco_metrics.simulation_actualized_annual_costs(evaler)) - print(eco_metrics.average_cost(evaler, 19)) - print(eco_metrics.benefit(evaler, 19)) + # print(eco_metrics.simulation_actualized_annual_costs(evaler)) + # print(eco_metrics.average_cost(evaler, 19)) + # print(eco_metrics.benefit(evaler, 19)) @dbtest @@ -610,13 +610,14 @@ def test_lcoe(db, fname, backend): # Reactor / Institution level obs_1 = eco_metrics.lcoe(evaler, agentsId=[17, 18, 19, 20, 21]) - print(obs_1) obs_2 = eco_metrics.child_lcoe(evaler, agentsId=[16]) - print(obs_2) - assert_equal(obs_1, obs_2) - # # Region / Institution level + + # Region / Institution level + obs_3 = eco_metrics.all_lcoe(evaler, + agentsId=[15]) + assert_equal(obs_1, obs_3) # assert_equal(eco_metrics.region_lcoe(evaler, 8), # eco_metrics.institution_lcoe(evaler, 9)) # # Simulation / Reactor level From 9ba52c022161aa4c1b6e6d7f3acef693c2774529 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Thu, 11 Jun 2020 21:21:28 -0500 Subject: [PATCH 58/64] some cleaning --- cymetric/eco_metrics.py | 559 ++++++++++------------------------------ 1 file changed, 137 insertions(+), 422 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index bb488f21..b354e65d 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -517,6 +517,36 @@ def simulation_actualized_annual_costs(outputDb, capital=True): return all_actualized_annual_costs(outputDb, capital=capital) +def actualized_annual_cost(evaler, agents=(), agentsId=(), capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + cost = actualized_annual_cost(evaler, agents, agentsId, capital): + cost['Cost'] = cost['Fuel'] + cost['OperationMaintenance'] + \ + cost['Capital'] + cost['Decommission'] + return cost[['Year', 'AgentId', 'Cost']] + + +def child_actualized_annual_cost(evaler, agents=(), agentsId=(), capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + cost = child_actualized_annual_cost(evaler, agents, agentsId, capital): + cost['Cost'] = cost['Fuel'] + cost['OperationMaintenance'] + \ + cost['Capital'] + cost['Decommission'] + return cost[['Year', 'AgentId', 'Cost']]s + + +def all_actualized_annual_cost(evaler, agents=[], agentsId=[], capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + cost = all_actualized_annual_cost(evaler, agents, agentsId, capital): + cost['Cost'] = cost['Fuel'] + cost['OperationMaintenance'] + \ + cost['Capital'] + cost['Decommission'] + return cost[['Year', 'AgentId', 'Cost']] + + def average_cost(evaler, reactorId, capital=True): """Input : evaler, reactor's AgentId Output : value (in $/MWh) corresponding to the total costs (sum of annual @@ -549,6 +579,42 @@ def power_generated(evaler, agentsId=[]): return dfPower[dfPower['AgentId'].isin(agentsId)] +def child_power_generated(evaler, agentsId=[]): + """Input : cymetric evaler and reactor agent id + Output : Electricity generated in MWh every year + """ + dfPower = evaler.eval('AnnualElectricityGeneratedByAgent').copy() + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + + # Convert to absolute time + dfPower['Year'] = dfPower['Year'] + initialYear + # Convert Power to MWh + dfPower['Energy'] *= 365.25 * 24 + + childId = eco_tools.get_child_id(agentsId, dfEntry) + + # Return table filtered by AgentsId + return dfPower[dfPower['AgentId'].isin(childId)] + + +def all_power_generated(evaler, agentsId=[]): + """Input : cymetric evaler and reactor agent id + Output : Electricity generated in MWh every year + """ + dfPower = evaler.eval('AnnualElectricityGeneratedByAgent').copy() + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + + # Convert to absolute time + dfPower['Year'] = dfPower['Year'] + initialYear + # Convert Power to MWh + dfPower['Energy'] *= 365.25 * 24 + + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + + # Return table filtered by AgentsId + return dfPower[dfPower['AgentId'].isin(agentsId)] + + def benefit(evaler, reactorId): """Input : evaler database and reactor agent id Output : cumulative sum of actualized income and expense @@ -642,101 +708,84 @@ def all_lcoe(evaler, agentsId=[]): return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() -def period_costs(outputDb, reactorId, t0=0, period=20, capital=True): - """Input : sqlite output database, reactor id, time window (t0, period) +def period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): + """Input : evaler database, agents id, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEcoInfo.loc[:, ('Truncation', 'End')] - costs = annual_costs(outputDb, reactorId, capital) - costs = costs.sum(axis=1) - power = power_generated(outputDb, reactorId) - df = pd.DataFrame(index=list( - range(initialYear, initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - - 1) // 12 + initialYear # year instead of months - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ - (1 + default_discount_rate) - \ - df.loc[j - 1 + t0, 'Power'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Power'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] *\ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Costs'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = rtn['Ratio'] * actualization - return rtn + costs = actualized_annual_cost(evaler, agentsId=agentsId, capital=capital) + power = power_generated(evaler, agentsId) + if t0 > 0 or period > 0: + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + + if (t0 > 0): + costs = costs[costs['Year'] >= t0+initialYear] + power = power[power['Year'] >= t0+initialYear] + if period > 0: + costs = costs[costs['Year'] <= t0+initialYear+period] + power = power[power['Year'] <= t0+initialYear+period] + base_col = ['AgentId', 'Year'] + added_col = base_col + ['Cost'] + costs = merge(power_income, base_col, costs, added_col) + costs['Cost'] *= 1 / costs['Energy'] + + return costs[[['Year', 'AgentId', 'Cost']]] -def period_costs2(outputDb, reactorId, t0=0, period=20, capital=True): - """Just for tests : another way to calculate the period costs + +def child_period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): + """Input : evaler database, agents id, time window (t0, period) + Output : cost at each time step t corresponding to actualized sum of + expense in [t+t0, t+t0+period] divided by actualized power generated + in [t+t0, t+t0+period] """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - costs = annual_costs(outputDb, institutionId, capital) - costs = costs.sum(axis=1) - power = power_generated(outputDb, institutionId) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + - duration // - 12 + - 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEcoInfo.loc[:, ('Truncation', 'End')] - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - j) - # tmp['WasteManagement'][j] = pd.Series() - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - return rtn + + costs = child_actualized_annual_cost( + evaler, agentsId=agentsId, capital=capital) + power = power_generated(evaler, agentsId) + if t0 > 0 or period > 0: + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + + if (t0 > 0): + costs = costs[costs['Year'] >= t0+initialYear] + power = power[power['Year'] >= t0+initialYear] + if period > 0: + costs = costs[costs['Year'] <= t0+initialYear+period] + power = power[power['Year'] <= t0+initialYear+period] + base_col = ['AgentId', 'Year'] + added_col = base_col + ['Cost'] + costs = merge(power_income, base_col, costs, added_col) + costs['Cost'] *= 1 / costs['Energy'] + + return costs[[['Year', 'AgentId', 'Cost']]] + + +def all_period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): + """Input : evaler database, agents id, time window (t0, period) + Output : cost at each time step t corresponding to actualized sum of + expense in [t+t0, t+t0+period] divided by actualized power generated + in [t+t0, t+t0+period] + """ + + costs = all_actualized_annual_cost( + evaler, agentsId=agentsId, capital=capital) + power = power_generated(evaler, agentsId) + if t0 > 0 or period > 0: + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + + if (t0 > 0): + costs = costs[costs['Year'] >= t0+initialYear] + power = power[power['Year'] >= t0+initialYear] + if period > 0: + costs = costs[costs['Year'] <= t0+initialYear+period] + power = power[power['Year'] <= t0+initialYear+period] + base_col = ['AgentId', 'Year'] + added_col = base_col + ['Cost'] + costs = merge(power_income, base_col, costs, added_col) + costs['Cost'] *= 1 / costs['Energy'] + + return costs[[['Year', 'AgentId', 'Cost']]] # Institution level @@ -758,142 +807,6 @@ def institution_benefit(outputDb, institutionId): return rtn -def institution_period_costs( - outputDb, institutionId, t0=0, period=20, capital=True): - """Input : sqlite output database, institution id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of - expense in [t+t0, t+t0+period] divided by actualized power generated in - [t+t0, t+t0+period] - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() - simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] - costs = institution_annual_costs( - outputDb, institutionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = institution_power_generated( - outputDb, institutionId, truncate=False) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + duration // 12 + 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Power'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Power'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Costs'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = rtn['Ratio'] * actualization - return rtn - - -def institution_period_costs2( - outputDb, institutionId, t0=0, period=20, capital=True): - """Just for tests : another method for period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEconomicInfo = evaler.eval('EconomicInfo').reset_index() - simulationBegin = dfEconomicInfo.loc[:, ('Truncation', 'Begin')] - simulationEnd = dfEconomicInfo.loc[:, ('Truncation', 'End')] - costs = institution_annual_costs( - outputDb, institutionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = institution_power_generated( - outputDb, institutionId, truncate=False) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + - duration // - 12 + - 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - return rtn - - -def institution_power_generated(outputDb, institutionId, truncate=True): - """Input : sqlite output database and institution agent id - Output : Sum of electricity generated in MWh every year in the institution - reactor fleet - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId == institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - dfPower = evaler.eval('TimeSeriesPower') - reactorIds = dfEntry[dfEntry['AgentId'].apply( - lambda x: isreactor(dfPower, x))]['AgentId'].tolist() - dfPower = evaler.eval('TimeSeriesPower').reset_index() - dfPower = dfPower[dfPower['AgentId'].apply(lambda x: x in reactorIds)] - dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear - dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, - index=list(range(initialYear, - initialYear + (initialMonth + duration) // - 12 + 1))) - rtn.name = 'Power in MWh' - return rtn.fillna(0) - - def institution_average_lcoe(outputDb, institutionId): """Input : sqlite output database and institution agent id Output : Variable cost corresponding at each time step (i.e. every year) @@ -969,159 +882,6 @@ def region_benefit(outputDb, regionId): return rtn -def region_period_costs(outputDb, regionId, t0=0, period=20, capital=True): - """Input : sqlite output database, region id, time window (t0, period) - Output : cost at each time step t corresponding to actualized sum of - expense in [t+t0, t+t0+period] divided by actualized power generated - in [t+t0, t+t0+period] - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = region_annual_costs(outputDb, regionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = region_power_generated(outputDb, regionId, truncate=False) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + - duration // - 12 + - 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd + 1): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Power'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Power'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Costs'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = rtn['Ratio'] * actualization - return rtn - - -def region_period_costs2(outputDb, regionId, t0=0, period=20, capital=True): - """Just for tests : another method to calculate period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = region_annual_costs(outputDb, regionId, capital, truncate=False) - costs = costs.sum(axis=1) - power = region_power_generated(outputDb, regionId, truncate=False) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + - duration // - 12 + - 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - return rtn - - -def region_power_generated(outputDb, regionId, truncate=True): - """Input : sqlite output database and region agent id - Output : Sum of electricity generated in MWh every years in the region - reactor fleet - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - tmp = dfEntry[dfEntry.ParentId == regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - institutionIds = tmp[tmp.Kind == 'Inst']['AgentId'].tolist() - reactorIds = [] - for id in institutionIds: - dfEntry2 = dfEntry[dfEntry.ParentId == id] - reactorIds += dfEntry2[dfEntry2['Spec'].apply( - lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - dfPower = evaler.eval('TimeSeriesPower').reset_index() - dfPower = dfPower[dfPower['AgentId'].apply(lambda x: x in reactorIds)] - dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear - dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, - index=list(range(initialYear, - initialYear + (initialMonth + duration) // - 12 + 1))) - rtn.name = 'Power in MWh' - return rtn.fillna(0) - - -def region_lcoe(outputDb, regionId): - """Input : sqlite output database and region agent id - Output : Value corresponding to Levelized Cost of Electricity ($/MWh) - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfEcoInfo = evaler.eval('EconomicInfo') - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - discountRate = dfEcoInfo.loc[regionId, ('Finance', 'DiscountRate')] - annualCosts = region_annual_costs(outputDb, regionId) - powerGenerated = region_power_generated(outputDb, regionId) - actualization = actualization_vector(powerGenerated.size, discountRate) - actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ - ((powerGenerated * actualization).fillna(0).sum()) - - def region_average_lcoe(outputDb, regionId): """Input : sqlite output database and region agent id Output : Variable cost corresponding at each time step (i.e. every year) @@ -1324,51 +1084,6 @@ def simulation_period_costs(outputDb, t0=0, period=20, capital=True): return rtn -def simulation_period_costs2(outputDb, t0=0, period=20, capital=True): - """Just for tests : another method to calculate the period costs - """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = simulation_annual_costs( - outputDb, - capital, - truncate=False).sum( - axis=1) - power = simulation_power_generated(outputDb, truncate=False) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + - duration // - 12 + - 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for j in range(simulationBegin, simulationEnd + 1): - for i in range(j + t0, j + t0 + period): - rtn.loc[j, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - j) - rtn.loc[j, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - j) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - return rtn - - def simulation_power_generated(outputDb, truncate=True): """Input : sqlite output database Output : Electricity generated in MWh every years by all the reactors of From 87fdb9dec9febab0faef8482ab01ade2bb8cc5c3 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 12 Jun 2020 14:00:06 -0500 Subject: [PATCH 59/64] this is working --- cymetric/eco_metrics.py | 632 ++++++++------------------------------ tests/test_eco_metrics.py | 294 ++++++++++-------- 2 files changed, 286 insertions(+), 640 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index b354e65d..5e826382 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -194,7 +194,7 @@ def decommissioning_cost(dfPower, dfEntry, dfInfo): if (len(tmp) == 1): duration = int(tmp.at[0, 'decom_duration']) overnightCost = tmp.at[0, 'decom_overnight_cost'] - cashFlowShape = capital_shape( + cashFlowShape = eco_tools.capital_shape( duration - duration // 2, duration // 2) powerCapacity = dfPower[dfPower['AgentId'] == id].reset_index().at[0, 'Value'] @@ -350,21 +350,10 @@ def child_annual_costs(evaler, agents=(), agentsId=(), capital=True): Output : total reactor costs per year over its lifetime at the institution level. """ - dfEntry = evaler.eval('AgentEntry') - - if len(agents) != 0: - agentsId += dfEntry[dfEntry['Prototype'].isin( - agents)]["AgentId"].tolist() - childId = eco_tools.get_child_id(agentsId, dfEntry) - - costs = annual_costs(evaler, agentsId=childId) - - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum().reset_index() - return costs + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + return annual_costs(evaler, agentsId=childId, capital=capital) def all_annual_costs(evaler, agents=(), agentsId=(), capital=True): @@ -380,20 +369,9 @@ def all_annual_costs(evaler, agents=(), agentsId=(), capital=True): Output : total reactor costs per year over its lifetime at the region level. """ - dfEntry = evaler.eval('AgentEntry') - - if len(agents) != 0: - agentsId += dfEntry[dfEntry['Prototype'].isin( - agents)]["AgentId"].tolist() - agentsId += eco_tools.get_child_id(agentsId, dfEntry) - costs = annual_costs(evaler, agentsId=agentsId) - - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum().reset_index() - return costs + return annual_costs(evaler, agentsId=agentsId, capital=capital) def actualize_costs(df, columns, dfEntry, time_col='Time', time_factor=12., t_0=0): @@ -451,7 +429,6 @@ def actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): costs = costs[costs['AgentId'].isin(agentsId)] dfInfo = evaler.eval('Info') - duration = dfInfo.loc[0, 'Duration'] initialYear = dfInfo.loc[0, 'InitialYear'] initialMonth = dfInfo.loc[0, 'InitialMonth'] @@ -469,59 +446,25 @@ def child_actualized_annual_costs(evaler, agents=(), agentsId=(), capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - - dfEntry = evaler.eval('AgentEntry').copy() - - if len(agents) != 0: - agentsId += dfEntry[dfEntry['Prototype'].isin( - agents)]["AgentId"].tolist() - + dfEntry = evaler.eval('AgentEntry') childId = eco_tools.get_child_id(agentsId, dfEntry) - - costs = actualized_annual_costs(evaler, agentsId=childId) - - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum().reset_index() - costs['AgentId'] = -1 - return costs + return actualized_annual_costs(evaler, agentsId=childId, capital=capital) def all_actualized_annual_costs(evaler, agents=[], agentsId=[], capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - - dfEntry = evaler.eval('AgentEntry').copy() - - if len(agents) != 0: - agentsId += dfEntry[dfEntry['Prototype'].isin( - agents)]["AgentId"].tolist() - + dfEntry = evaler.eval('AgentEntry') agentsId += eco_tools.get_child_id(agentsId, dfEntry) - - costs = actualized_annual_costs(evaler, agentsId=agentsId) - - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum().reset_index() - costs['AgentId'] = -1 - - return costs - - -def simulation_actualized_annual_costs(outputDb, capital=True): - """Same as annual_cost except all values are actualized to the begin date - of the SIMULATION - """ - return all_actualized_annual_costs(outputDb, capital=capital) + return actualized_annual_costs(evaler, agentsId=agentsId, capital=capital) def actualized_annual_cost(evaler, agents=(), agentsId=(), capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - cost = actualized_annual_cost(evaler, agents, agentsId, capital): + cost = actualized_annual_costs(evaler, agents, agentsId, capital) cost['Cost'] = cost['Fuel'] + cost['OperationMaintenance'] + \ cost['Capital'] + cost['Decommission'] return cost[['Year', 'AgentId', 'Cost']] @@ -531,17 +474,17 @@ def child_actualized_annual_cost(evaler, agents=(), agentsId=(), capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - cost = child_actualized_annual_cost(evaler, agents, agentsId, capital): + cost = child_actualized_annual_costs(evaler, agents, agentsId, capital) cost['Cost'] = cost['Fuel'] + cost['OperationMaintenance'] + \ cost['Capital'] + cost['Decommission'] - return cost[['Year', 'AgentId', 'Cost']]s + return cost[['Year', 'AgentId', 'Cost']] def all_actualized_annual_cost(evaler, agents=[], agentsId=[], capital=True): """Same as annual_cost except all values are actualized to the begin date of the SIMULATION """ - cost = all_actualized_annual_cost(evaler, agents, agentsId, capital): + cost = all_actualized_annual_costs(evaler, agents, agentsId, capital) cost['Cost'] = cost['Fuel'] + cost['OperationMaintenance'] + \ cost['Capital'] + cost['Decommission'] return cost[['Year', 'AgentId', 'Cost']] @@ -583,48 +526,30 @@ def child_power_generated(evaler, agentsId=[]): """Input : cymetric evaler and reactor agent id Output : Electricity generated in MWh every year """ - dfPower = evaler.eval('AnnualElectricityGeneratedByAgent').copy() - initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - - # Convert to absolute time - dfPower['Year'] = dfPower['Year'] + initialYear - # Convert Power to MWh - dfPower['Energy'] *= 365.25 * 24 - + dfEntry = evaler.eval('AgentEntry') childId = eco_tools.get_child_id(agentsId, dfEntry) - - # Return table filtered by AgentsId - return dfPower[dfPower['AgentId'].isin(childId)] + return power_generated(evaler, agentsId=childId) def all_power_generated(evaler, agentsId=[]): """Input : cymetric evaler and reactor agent id Output : Electricity generated in MWh every year """ - dfPower = evaler.eval('AnnualElectricityGeneratedByAgent').copy() - initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - - # Convert to absolute time - dfPower['Year'] = dfPower['Year'] + initialYear - # Convert Power to MWh - dfPower['Energy'] *= 365.25 * 24 - + dfEntry = evaler.eval('AgentEntry') agentsId += eco_tools.get_child_id(agentsId, dfEntry) + return power_generated(evaler, agentsId=agentsId) - # Return table filtered by AgentsId - return dfPower[dfPower['AgentId'].isin(agentsId)] - -def benefit(evaler, reactorId): +def benefit(evaler, agentsId=[]): """Input : evaler database and reactor agent id Output : cumulative sum of actualized income and expense (= - expenditures + income) """ costs = actualized_annual_costs(evaler=evaler, - agentsId=[reactorId]) + agentsId=agentsId) power_income = power_generated(evaler=evaler, - agentsId=[reactorId]) - power_income["Energy"] *= lcoe(evaler=evaler, agentsId=[reactorId]) + agentsId=agentsId) + power_income["Energy"] *= lcoe(evaler=evaler, agentsId=agentsId) base_col = ['AgentId', 'Year'] added_col = base_col + ['Fuel', @@ -642,12 +567,30 @@ def benefit(evaler, reactorId): return power_income[['SimId', 'AgentId', 'Year', 'Capital']] +def child_benefit(evaler, agentsId=[]): + """Input : sqlite output database and institution agent id + Output : cumulative sum of income and expense (= - expenditures + income) + """ + dfEntry = evaler.eval('AgentEntry').copy() + childsId = eco_tools.get_child_id(agentsId, dfEntry) + return benefit(evaler, childsId) + + +def all_benefit(evaler, agentsId=[]): + """Input : sqlite output database and institution agent id + Output : cumulative sum of income and expense (= - expenditures + income) + """ + dfEntry = evaler.eval('AgentEntry').copy() + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + return benefit(evaler, agentsId) + + def lcoe(evaler, agentsId=[]): """Input : evaler database and agents id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) """ - costs = actualized_annual_costs(evaler=evaler, - agentsId=agentsId).drop(['AgentId', 'Year'], axis=1) + costs = actualized_annual_cost(evaler=evaler, + agentsId=agentsId).drop(['AgentId', 'Year'], axis=1) power = power_generated(evaler=evaler, agentsId=agentsId) initialYear = evaler.eval('Info').loc[0, 'InitialYear'] @@ -664,48 +607,20 @@ def lcoe(evaler, agentsId=[]): def child_lcoe(evaler, agentsId=[]): """Input : evaler database and Instutions/Region id - Output : Value corresponding to Levelized Cost of Electricity ($/MWh) + Output : Value corresponding to Levelized Cost of Electricity ($/MWh) of the child agents """ dfEntry = evaler.eval('AgentEntry').copy() - childId = eco_tools.get_child_id(agentsId, dfEntry) - - costs = child_actualized_annual_costs(evaler=evaler, - agentsId=childId).drop(['AgentId', 'Year'], axis=1) - power = power_generated(evaler=evaler, agentsId=childId) - - initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - dfEntry = evaler.eval('AgentEntry') - actualized_power = actualize_costs(df=power, - columns=["Energy"], - dfEntry=dfEntry, - time_col="Year", - time_factor=1., - t_0=initialYear).drop(['SimId', 'AgentId', 'Year'], axis=1) - - return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() + childsId = eco_tools.get_child_id(agentsId, dfEntry) + return lcoe(evaler, agentsId=childsId) def all_lcoe(evaler, agentsId=[]): - """Input : sqlite output database and Instutions/Region agent id + """Input : evaler database and Instutions/Region id Output : Value corresponding to Levelized Cost of Electricity ($/MWh) """ dfEntry = evaler.eval('AgentEntry').copy() agentsId += eco_tools.get_child_id(agentsId, dfEntry) - - costs = actualized_annual_costs(evaler=evaler, - agentsId=agentsId).drop(['AgentId', 'Year'], axis=1) - power = power_generated(evaler=evaler, agentsId=agentsId) - - initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - dfEntry = evaler.eval('AgentEntry') - actualized_power = actualize_costs(df=power, - columns=["Energy"], - dfEntry=dfEntry, - time_col="Year", - time_factor=1., - t_0=initialYear).drop(['SimId', 'AgentId', 'Year'], axis=1) - - return (costs.sum(axis=1)).sum() / actualized_power.sum().sum() + return lcoe(evaler, agentsId=agentsId) def period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): @@ -719,7 +634,6 @@ def period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): power = power_generated(evaler, agentsId) if t0 > 0 or period > 0: initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - if (t0 > 0): costs = costs[costs['Year'] >= t0+initialYear] power = power[power['Year'] >= t0+initialYear] @@ -728,10 +642,10 @@ def period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): power = power[power['Year'] <= t0+initialYear+period] base_col = ['AgentId', 'Year'] added_col = base_col + ['Cost'] - costs = merge(power_income, base_col, costs, added_col) + costs = merge(power, base_col, costs, added_col) costs['Cost'] *= 1 / costs['Energy'] - return costs[[['Year', 'AgentId', 'Cost']]] + return costs[['Year', 'AgentId', 'Cost']] def child_period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): @@ -740,25 +654,9 @@ def child_period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ - - costs = child_actualized_annual_cost( - evaler, agentsId=agentsId, capital=capital) - power = power_generated(evaler, agentsId) - if t0 > 0 or period > 0: - initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - - if (t0 > 0): - costs = costs[costs['Year'] >= t0+initialYear] - power = power[power['Year'] >= t0+initialYear] - if period > 0: - costs = costs[costs['Year'] <= t0+initialYear+period] - power = power[power['Year'] <= t0+initialYear+period] - base_col = ['AgentId', 'Year'] - added_col = base_col + ['Cost'] - costs = merge(power_income, base_col, costs, added_col) - costs['Cost'] *= 1 / costs['Energy'] - - return costs[[['Year', 'AgentId', 'Cost']]] + dfEntry = evaler.eval('AgentEntry').copy() + childsId = eco_tools.get_child_id(agentsId, dfEntry) + return period_costs(evaler, agentsId=childsId, t0=t0, period=period, capital=capital) def all_period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): @@ -767,186 +665,85 @@ def all_period_costs(evaler, agentsId=[], t0=0, period=0, capital=True): expense in [t+t0, t+t0+period] divided by actualized power generated in [t+t0, t+t0+period] """ - - costs = all_actualized_annual_cost( - evaler, agentsId=agentsId, capital=capital) - power = power_generated(evaler, agentsId) - if t0 > 0 or period > 0: - initialYear = evaler.eval('Info').loc[0, 'InitialYear'] - - if (t0 > 0): - costs = costs[costs['Year'] >= t0+initialYear] - power = power[power['Year'] >= t0+initialYear] - if period > 0: - costs = costs[costs['Year'] <= t0+initialYear+period] - power = power[power['Year'] <= t0+initialYear+period] - base_col = ['AgentId', 'Year'] - added_col = base_col + ['Cost'] - costs = merge(power_income, base_col, costs, added_col) - costs['Cost'] *= 1 / costs['Energy'] - - return costs[[['Year', 'AgentId', 'Cost']]] + dfEntry = evaler.eval('AgentEntry').copy() + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + return period_costs(evaler, agentsId=agentsId, t0=t0, period=period, capital=capital) # Institution level -def institution_benefit(outputDb, institutionId): - """Input : sqlite output database and institution agent id - Output : cumulative sum of income and expense (= - expenditures + income) - """ - costs = - institution_annual_costs(outputDb, institutionId).sum(axis=1) - power_gen = institution_power_generated( - outputDb, institutionId) * institution_average_lcoe( - outputDb, institutionId)['Average LCOE'] - rtn = pd.concat([costs, power_gen], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn - - -def institution_average_lcoe(outputDb, institutionId): - """Input : sqlite output database and institution agent id +def average_lcoe(evaler, agentsId=[]): + """Input : evaler database and a list of agents id Output : Variable cost corresponding at each time step (i.e. every year) to the weighted average of the reactors Levelized Cost of Electricity ($/MWh). A reactor is taken into account at a time step t only if it is active (i.e. already commissioned and not yet decommissioned) at this time step. """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry.ParentId == institutionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - dfPower = evaler.eval('TimeSeriesPower') - reactorIds = dfEntry[dfEntry['AgentId'].apply( - lambda x: isreactor(dfPower, x))]['AgentId'].tolist() - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - dfPower = evaler.eval('TimeSeriesPower') - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Weighted sum'] = 0 - rtn['Power'] = 0 - rtn['Temp'] = pd.Series() - rtn['Temp2'] = pd.Series() - for id in reactorIds: - tmp = lcoe(outputDb, id) - commissioning = dfEntry[dfEntry.AgentId == id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'].iloc[0] - decommissioning = (commissioning + lifetime + - initialMonth - 1) // 12 + initialYear - commissioning = (commissioning + initialMonth - 1) // 12 + initialYear - power = dfPower[dfPower.AgentId == id]['Value'].iloc[0] - rtn['Temp'] = pd.Series( - tmp, - index=list( - range( - commissioning, - decommissioning + 1))) * power - rtn['Weighted sum'] += rtn['Temp'].fillna(0) - rtn['Temp2'] = pd.Series( - power, - index=list( - range(commissioning, - decommissioning + 1))).fillna(0) - rtn['Power'] += rtn['Temp2'].fillna(0) - rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] - return rtn.fillna(0) + costs = actualized_annual_cost(evaler=evaler, + agentsId=agentsId) + power = power_generated(evaler=evaler, agentsId=agentsId) + + initialYear = evaler.eval('Info').loc[0, 'InitialYear'] + dfEntry = evaler.eval('AgentEntry') + actualized_power = actualize_costs(df=power, + columns=["Energy"], + dfEntry=dfEntry, + time_col="Year", + time_factor=1., + t_0=initialYear) + base_col = ['AgentId', 'Year'] + added_col = base_col + ['Cost'] + costs = merge(actualized_power, base_col, costs, added_col) + costs["Cost"] *= 1 / costs["Energy"] + costs.drop(["AgentId"], axis=1, inplace=True) + costs = costs.groupby(['SimId', 'Year']).sum().reset_index() + + return costs[['SimId', 'Year', 'Cost']] + # Region level -def region_benefit(outputDb, regionId): - """Input : sqlite output database and region agent id - Output : cumulative sum of actualized income and expense - (= - expenditures + income) +def child_average_lcoe(evaler, agentsId=[]): + """Input : evaler database and list of regions/Institution/Agent agent id + Output : Variable cost corresponding at each time step (i.e. every year) + to the weighted average of the reactors Levelized Cost of Electricity + ($/MWh). A reactor is taken into account at a time step t if and only if + it is active (i.e. already commissioned and not yet decommissioned) at + this time step. """ - costs = - region_annual_costs(outputDb, regionId).sum(axis=1) - power_gen = region_power_generated(outputDb, regionId) * \ - region_average_lcoe(outputDb, regionId)['Average LCOE'] - rtn = pd.concat([costs, power_gen], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn + dfEntry = evaler.eval('AgentEntry') + childId = eco_tools.get_child_id(agentsId, dfEntry) + return average_lcoe(evaler, childId) -def region_average_lcoe(outputDb, regionId): - """Input : sqlite output database and region agent id +def all_average_lcoe(evaler, agentsId=[]): + """Input : evaler database and list of regions/Institution/Agent agent id Output : Variable cost corresponding at each time step (i.e. every year) to the weighted average of the reactors Levelized Cost of Electricity ($/MWh). A reactor is taken into account at a time step t if and only if it is active (i.e. already commissioned and not yet decommissioned) at this time step. """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - tmp = dfEntry[dfEntry.ParentId == regionId] - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - institutionsId = tmp[tmp.Kind == 'Inst']['AgentId'].tolist() - reactorIds = [] - dfPower = evaler.eval('TimeSeriesPower') - for id in institutionsId: - dfEntry2 = dfEntry[dfEntry.ParentId == id] - reactorIds += dfEntry2[dfEntry2['Spec'].apply( - lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Weighted sum'] = 0 - rtn['Power'] = 0 - rtn['Temp'] = pd.Series() - rtn['Temp2'] = pd.Series() - for id in reactorIds: - tmp = lcoe(outputDb, id) - commissioning = dfEntry[dfEntry.AgentId == id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'].iloc[0] - decommissioning = (commissioning + lifetime + - initialMonth - 1) // 12 + initialYear - commissioning = (commissioning + initialMonth - 1) // 12 + initialYear - power = dfPower[dfPower.AgentId == id]['Value'].iloc[0] - rtn['Temp'] = pd.Series( - tmp, - index=list( - range( - commissioning, - decommissioning + 1))) * power - rtn['Weighted sum'] += rtn['Temp'].fillna(0) - rtn['Temp2'] = pd.Series( - power, - index=list( - range( - commissioning, - decommissioning + - 1))).fillna(0) - rtn['Power'] += rtn['Temp2'] - rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] - return rtn.fillna(0) + dfEntry = evaler.eval('AgentEntry') + agentsId += eco_tools.get_child_id(agentsId, dfEntry) + return average_lcoe(evaler, agentsId) + # Simulation level -def simulation_annual_costs(outputDb, capital=True, truncate=True): +def simulation_actualized_annual_costs(evaler, capital=True): + """Same as annual_cost except all values are actualized to the begin date + of the SIMULATION + """ + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_actualized_annual_costs(evaler, agentsId=all_ids, capital=capital) + + +def simulation_annual_costs(evaler, capital=True, truncate=True): """Input : sqlite output database. It is possible not to take into account the construction costs (capital=False) if the reactors are supposed to have been built before the beginning of the simulation. It is also @@ -958,233 +755,56 @@ def simulation_annual_costs(outputDb, capital=True, truncate=True): Output : total reactor costs per year over its lifetime at the simulation level. """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - reactorIds = dfEntry[dfEntry['Spec'].apply( - lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - dfCapitalCosts = evaler.eval('CapitalCost').reset_index() - dfCapitalCosts = dfCapitalCosts[dfCapitalCosts['AgentId'].apply( - lambda x: x in reactorIds)] - mini = min(dfCapitalCosts['Time']) - dfCapitalCosts = dfCapitalCosts.groupby('Time').sum() - costs = pd.DataFrame( - {'Capital': dfCapitalCosts['Payment']}, index=list(range(0, duration))) - dfDecommissioningCosts = evaler.eval('DecommissioningCost').reset_index() - if not dfDecommissioningCosts.empty: - dfDecommissioningCosts = dfDecommissioningCosts[ - dfDecommissioningCosts['AgentId'].apply(lambda x: x in reactorIds)] - dfDecommissioningCosts = dfDecommissioningCosts.groupby('Time').sum() - costs['Decommissioning'] = dfDecommissioningCosts['Payment'] - dfOMCosts = evaler.eval('OperationMaintenance').reset_index() - dfOMCosts = dfOMCosts[dfOMCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfOMCosts = dfOMCosts.groupby('Time').sum() - costs['OperationAndMaintenance'] = dfOMCosts['Payment'] - dfFuelCosts = evaler.eval('FuelCost').reset_index() - dfFuelCosts = dfFuelCosts[dfFuelCosts['AgentId'].apply( - lambda x: x in reactorIds)] - dfFuelCosts = dfFuelCosts.groupby('Time').sum() - costs['Fuel'] = dfFuelCosts['Payment'] - costs = costs.fillna(0) - costs['Year'] = (costs.index + initialMonth - 1) // 12 + initialYear - if truncate: - endYear = (simulationEnd + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x: x <= endYear)] - beginYear = (simulationBegin + initialMonth - 1) // 12 + initialYear - costs = costs[costs['Year'].apply(lambda x: x >= beginYear)] - if not capital: - del costs['Capital'] - costs = costs.groupby('Year').sum() - return costs + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_annual_costs(evaler, capital=capital) -def simulation_benefit(outputDb): - """Input : sqlite output database +def simulation_benefit(evaler): + """Input : evaler database Output : cumulative sum of total income and total expense (= - expenditures + income) when all reactors of the simulation are taken into account """ - costs = - simulation_annual_costs(outputDb).sum(axis=1) - power_gen = simulation_power_generated( - outputDb) * simulation_average_lcoe(outputDb)['Average LCOE'] - rtn = pd.concat([costs, power_gen], axis=1).fillna(0) - rtn['Capital'] = (rtn[0] + rtn[1]).cumsum() - actualization = actualization_vector(len(rtn)) - actualization.index = rtn.index - rtn['Actualized'] = ((rtn[0] + rtn[1]) * actualization).cumsum() - return rtn + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_benefit(evaler, agentsId=all_ids) -def simulation_period_costs(outputDb, t0=0, period=20, capital=True): - """Input : sqlite output database, time window (t0, period) +def simulation_period_costs(evaler, t0=0, period=20, capital=True): + """Input : evaler database, time window (t0, period) Output : cost at each time step t corresponding to actualized sum of total expense in [t+t0, t+t0+period] divided by total actualized power generated in [t+t0, t+t0+period] when all reactors of the simulation are taken into account """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - costs = simulation_annual_costs( - outputDb, - capital, - truncate=False).sum( - axis=1) - power = simulation_power_generated(outputDb, truncate=False) - df = pd.DataFrame( - index=list( - range( - initialYear, - initialYear + - duration // - 12 + - 1))) - df['Power'] = power - df['Costs'] = costs - df = df.fillna(0) - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd))) - rtn['Power'] = pd.Series() - rtn['Payment'] = pd.Series() - rtn = rtn.fillna(0) - for i in range(simulationBegin + t0, simulationBegin + t0 + period): - rtn.loc[simulationBegin, 'Power'] += df.loc[i, 'Power'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - rtn.loc[simulationBegin, 'Payment'] += df.loc[i, 'Costs'] / \ - (1 + default_discount_rate) ** (i - simulationBegin) - for j in range(simulationBegin + 1, simulationEnd): - rtn.loc[j, 'Power'] = rtn.loc[j - 1, 'Power'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Power'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Power'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn.loc[j, 'Payment'] = rtn.loc[j - 1, 'Payment'] * \ - (1 + default_discount_rate) - df.loc[j - 1 + t0, 'Costs'] * \ - (1 + default_discount_rate) ** (1 - t0) + \ - df.loc[j - 1 + period + t0, 'Costs'] / \ - (1 + default_discount_rate) ** (period + t0 - 1) - rtn['Ratio'] = rtn['Payment'] / rtn['Power'] * (rtn['Power'] > 1) - return rtn + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_period_costs(evaler, agentsId=all_ids, t0=t0, period=period, capital=capital) -def simulation_power_generated(outputDb, truncate=True): - """Input : sqlite output database +def simulation_power_generated(evaler): + """Input : evaler database Output : Electricity generated in MWh every years by all the reactors of the simulation """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - reactorIds = dfEntry[dfEntry['Spec'].apply( - lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - dfPower = evaler.eval('TimeSeriesPower').reset_index() - dfPower = dfPower[dfPower['AgentId'].apply(lambda x: x in reactorIds)] - dfPower['Year'] = (dfPower['Time'] + initialMonth - 1) // 12 + initialYear - dfPower = dfPower.groupby('Year').sum() - rtn = pd.Series(dfPower['Value'] * 8760 / 12, - index=list(range(initialYear, - initialYear + (initialMonth + duration) // - 12 + 1))) - rtn.name = 'Power in MWh' - return rtn.fillna(0) - - -def simulation_lcoe(outputDb): + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_power_generated(evaler, agentsId=all_ids) + + +def simulation_lcoe(evaler): """Input : sqlite output database Output : Value corresponding to Levelized Cost of Electricity ($/MWh) when taking into account all reactors commissioned in the simulation """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfEcoInfo = evaler.eval('EconomicInfo') - dfEcoInfo = dfEcoInfo.set_index(('Agent', 'AgentId')) - discountRate = dfEcoInfo.iloc[0, ('Finance', 'DiscountRate')] - annualCosts = simulation_annual_costs(outputDb) - powerGenerated = simulation_power_generated(outputDb) - actualization = actualization_vector(powerGenerated.size, discountRate) - actualization.index = powerGenerated.index.copy() - return (annualCosts.sum(axis=1) * actualization).fillna(0).sum() / \ - ((powerGenerated * actualization).fillna(0).sum()) - - -def simulation_average_lcoe(outputDb): - """Input : sqlite output database and region agent id + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_lcoe(evaler) + + +def simulation_average_lcoe(evaler): + """Input : evaler database and region agent id Output : Variable cost corresponding at each time step (i.e. every year) to the weighted average of the reactors Levelized Cost of Electricity ($/MWh). A reactor is taken into account at a time step t if and only if it is in activity (i.e. already commissioned and not yet decommissioned) at this time step. """ - db = dbopen(outputDb) - evaler = Evaluator(db, write=False) - dfInfo = evaler.eval('Info').reset_index() - duration = dfInfo.loc[0, 'Duration'] - initialYear = dfInfo.loc[0, 'InitialYear'] - initialMonth = dfInfo.loc[0, 'InitialMonth'] - dfEcoInfo = evaler.eval('EconomicInfo') - simulationBegin = dfEcoInfo[('Truncation', 'Begin')].iloc[0] - simulationEnd = dfEcoInfo[('Truncation', 'End')].iloc[0] - dfEntry = evaler.eval('AgentEntry').reset_index() - dfEntry = dfEntry[dfEntry['EnterTime'].apply( - lambda x: x > simulationBegin and x < simulationEnd)] - reactorIds = dfEntry[dfEntry['Spec'].apply( - lambda x: 'REACTOR' in x.upper())]['AgentId'].tolist() - simulationBegin = (simulationBegin + initialMonth - 1) // 12 + initialYear - simulationEnd = (simulationEnd + initialMonth - 1) // 12 + initialYear - dfPower = evaler.eval('TimeSeriesPower') - rtn = pd.DataFrame(index=list(range(simulationBegin, simulationEnd + 1))) - rtn['Weighted sum'] = 0 - rtn['Power'] = 0 - rtn['Temp'] = pd.Series() - rtn['Temp2'] = pd.Series() - for id in reactorIds: - tmp = lcoe(outputDb, id) - commissioning = dfEntry[dfEntry.AgentId == id]['EnterTime'].iloc[0] - lifetime = dfEntry[dfEntry.AgentId == id]['Lifetime'].iloc[0] - decommissioning = (commissioning + lifetime + - initialMonth - 1) // 12 + initialYear - commissioning = (commissioning + initialMonth - 1) // 12 + initialYear - power = dfPower[dfPower.AgentId == id]['Value'].iloc[0] - rtn['Temp'] = pd.Series( - tmp, - index=list( - range( - commissioning, - decommissioning + 1))) * power - rtn['Weighted sum'] += rtn['Temp'].fillna(0) - rtn['Temp2'] = pd.Series( - power, - index=list( - range( - commissioning, - decommissioning + - 1))) - rtn['Power'] += rtn['Temp2'].fillna(0) - rtn['Average LCOE'] = rtn['Weighted sum'] / rtn['Power'] - return rtn.fillna(0) + all_ids = evaler.eval('AgentEntry')['AgentId'].to_list() + return all_average_lcoe(evaler, agentsId=all_ids) diff --git a/tests/test_eco_metrics.py b/tests/test_eco_metrics.py index 15bf4f80..2f51bc25 100644 --- a/tests/test_eco_metrics.py +++ b/tests/test_eco_metrics.py @@ -19,13 +19,13 @@ def test_capital_cost(): exp = pd.DataFrame(np.array( - [(UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 0, 0.126000), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 1, 0.139965), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 2, 0.112035), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 3, 0.84000), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 4, 0.55965), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 5, 0.28035), - (UUID('4375a413-dafb-4da1-bfcc-f16e59b5a3e0'), 13, 6, 0.)], + [(UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 0, 0.126000), + (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 1, 0.139965), + (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 2, 0.112035), + (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 3, 0.084000), + (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 4, 0.055965), + (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 5, 0.028035), + (UUID('f22f2281-2464-420a-8325-37320fd418f8'), 13, 6, 0.)], dtype=ensure_dt_bytes( [('SimId', 'O'), ('AgentId', ' Date: Fri, 12 Jun 2020 14:03:26 -0500 Subject: [PATCH 60/64] remove unsused vars --- cymetric/eco_metrics.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cymetric/eco_metrics.py b/cymetric/eco_metrics.py index 5e826382..19d0d855 100644 --- a/cymetric/eco_metrics.py +++ b/cymetric/eco_metrics.py @@ -227,8 +227,7 @@ def operation_maintenance(dfPower, dfEntry): """The OperationMaintenance metric gives the cash flows at each time step corresponding to the reactor operations and maintenance costs. """ - exp = ['SimId', 'AgentId', 'Time', 'Payment'] - power = ['SimId', 'AgentId', 'Time', 'Value'] + ecoInfo = ['fixed', 'variable', 'operation_dev'] # Get eco data dfEcoInfo = eco_data.get_prototypes_eco() @@ -323,7 +322,6 @@ def annual_costs(evaler, agents=(), agentsId=(), capital=True): costs = costs[costs['AgentId'].isin(agentsId)] dfInfo = evaler.eval('Info') - duration = dfInfo.loc[0, 'Duration'] initialYear = dfInfo.loc[0, 'InitialYear'] initialMonth = dfInfo.loc[0, 'InitialMonth'] From c8c06258e10da6b0e3e129b68e438286ddc5af87 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 12 Jun 2020 14:07:46 -0500 Subject: [PATCH 61/64] pyyaml is required for eco --- circle.yml | 104 ++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/circle.yml b/circle.yml index 1a7f7147..e1b9a89a 100644 --- a/circle.yml +++ b/circle.yml @@ -9,18 +9,19 @@ jobs: steps: # Ensure your image has git (required by git to clone via SSH) so that CircleCI can clone your repo - run: apt-get -qq update; apt-get -y install git openssh-client + - run: pip install pyyaml - checkout - run: - name: Build Cymetric - command: | - python ./setup.py install --user + name: Build Cymetric + command: | + python ./setup.py install --user - run: - name: save SHA to a file - command: echo $CIRCLE_SHA1 > .circle-sha + name: save SHA to a file + command: echo $CIRCLE_SHA1 > .circle-sha - save_cache: - key: v1-repo-{{ checksum ".circle-sha" }} - paths: - - /root + key: v1-repo-{{ checksum ".circle-sha" }} + paths: + - /root # Test nosetest: @@ -29,18 +30,17 @@ jobs: working_directory: ~/root steps: - run: - name: save SHA to a file - command: echo $CIRCLE_SHA1 > .circle-sha + name: save SHA to a file + command: echo $CIRCLE_SHA1 > .circle-sha - restore_cache: - keys: - - v1-repo-{{ checksum ".circle-sha" }} + keys: + - v1-repo-{{ checksum ".circle-sha" }} - run: - name: Install nosetest - command: pip install nose + name: Install nosetest + command: pip install nose - run: - name: Nosetests - command: nosetests -w ~/cymetric/tests; exit $? - + name: Nosetests + command: nosetests -w ~/cymetric/tests; exit $? # Update docker container deploy: # Cymetric -> Cymetric:latest @@ -50,19 +50,19 @@ jobs: steps: - checkout - run: - name: Place the proper Dockerfile - command: cp docker/master-ci/Dockerfile . + name: Place the proper Dockerfile + command: cp docker/master-ci/Dockerfile . - setup_remote_docker - run: - name: log into Docker - command: | - docker login -u $DOCKER_USER -p $DOCKER_PASS + name: log into Docker + command: | + docker login -u $DOCKER_USER -p $DOCKER_PASS - run: - name: Build Docker container - command: docker build --rm=false -t cyclus/cymetric:latest . + name: Build Docker container + command: docker build --rm=false -t cyclus/cymetric:latest . - run: - name: Push on DockerHub - command: docker push cyclus/cymetric:latest # push to docker depot + name: Push on DockerHub + command: docker push cyclus/cymetric:latest # push to docker depot deploy_stable: # Cymetric:stable docker: @@ -71,47 +71,43 @@ jobs: steps: - checkout - run: - name: Place the proper Dockerfile - command: cp docker/release-ci/Dockerfile . + name: Place the proper Dockerfile + command: cp docker/release-ci/Dockerfile . - setup_remote_docker - run: - name: Log on DockerHub - command: | - docker login -u $DOCKER_USER -p $DOCKER_PASS + name: Log on DockerHub + command: | + docker login -u $DOCKER_USER -p $DOCKER_PASS - run: - name: Build Docker container - command: docker build -t cyclus/cymetric:stable . + name: Build Docker container + command: docker build -t cyclus/cymetric:stable . - run: - name: Push on DockerHub - command: docker push cyclus/cymetric:stable # push to docker depot - + name: Push on DockerHub + command: docker push cyclus/cymetric:stable # push to docker depot workflows: version: 2 build_and_test: jobs: - # on a pr // all branch - build - nosetest: - requires: - - build + requires: + - build # Merge on Master - deploy: - filters: - branches: - only: master - requires: - - nosetest - - - # The following should now be done on version tag. + filters: + branches: + only: master + requires: + - nosetest + # The following should now be done on version tag. - deploy_stable: - filters: - branches: - ignore: /.*/ - tags: - only: /.*/ - requires: - - nosetest + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + requires: + - nosetest From 6c0c1cc79f202f6c5b899c37b30926ee2f3fcf95 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 12 Jun 2020 14:14:48 -0500 Subject: [PATCH 62/64] reset metric.py formating --- cymetric/metrics.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cymetric/metrics.py b/cymetric/metrics.py index 26a95632..d3644dd0 100644 --- a/cymetric/metrics.py +++ b/cymetric/metrics.py @@ -106,7 +106,7 @@ def dec(f): ('NucId', ts.INT), ('Units', ts.STRING), ('Mass', ts.DOUBLE) -] + ] @metric(name='Materials', depends=_matdeps, schema=_matschema) @@ -138,7 +138,7 @@ def materials(rsrcs, comps): ('TimeCreated', ts.INT), ('NucId', ts.INT), ('Activity', ts.DOUBLE) -] + ] @metric(name='Activity', depends=_actdeps, schema=_actschema) @@ -177,7 +177,7 @@ def activity(mats): ('TimeCreated', ts.INT), ('NucId', ts.INT), ('DecayHeat', ts.DOUBLE) -] + ] @metric(name='DecayHeat', depends=_dhdeps, schema=_dhschema) @@ -210,7 +210,7 @@ def decay_heat(acts): _bsschema = [ ('SimId', ts.UUID), ('EnterTime', ts.INT), ('Prototype', ts.STRING), ('Count', ts.INT) -] + ] @metric(name='BuildSeries', depends=_bsdeps, schema=_bsschema) @@ -235,7 +235,7 @@ def build_series(entry): ('ExitTime', ts.INT), ('Prototype', ts.STRING), ('Count', ts.INT) -] + ] @metric(name='DecommissionSeries', depends=_dsdeps, schema=_dsschema) @@ -270,7 +270,7 @@ def decommission_series(entry, exit): ('Lifetime', ts.INT), ('EnterTime', ts.INT), ('ExitTime', ts.INT), -]) + ]) @metric(name='Agents', depends=_agentsdeps, schema=_agentsschema) @@ -318,7 +318,7 @@ def agents(entry, exit, decom, info): ('Commodity', ts.STRING), ('Units', ts.STRING), ('Quantity', ts.DOUBLE) -] + ] @metric(name='TransactionQuantity', depends=_transdeps, schema=_transschema) @@ -350,7 +350,7 @@ def transaction_quantity(mats, tranacts): ('InventoryName', ts.STRING), ('NucId', ts.INT), ('Quantity', ts.DOUBLE) -] + ] @metric(name='ExplicitInventoryByAgent', depends=_invdeps, schema=_invschema) @@ -381,7 +381,7 @@ def explicit_inventory_by_agent(expinv): ('InventoryName', ts.STRING), ('NucId', ts.INT), ('Quantity', ts.DOUBLE) -] + ] @metric(name='ExplicitInventoryByNuc', depends=_invdeps, schema=_invschema) @@ -411,7 +411,7 @@ def explicit_inventory_by_nuc(expinv): ('AgentId', ts.INT), ('Year', ts.INT), ('Energy', ts.DOUBLE) -] + ] @metric(name='AnnualElectricityGeneratedByAgent', depends=_egdeps, @@ -443,7 +443,7 @@ def annual_electricity_generated_by_agent(elec): ('AgentId', ts.INT), ('Month', ts.INT), ('Energy', ts.DOUBLE) -] + ] @metric(name='MonthlyElectricityGeneratedByAgent', depends=_egdeps, @@ -519,7 +519,7 @@ def inventory_quantity_per_gwe(inv, power): _tlschema = [ ('SimId', ts.UUID), ('TimeStep', ts.INT) -] + ] @metric(name='TimeList', depends=_tldeps, schema=_tlschema) From e4388864a6a2de2c93e2ad710650cb5c6e898862 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 12 Jun 2020 14:18:27 -0500 Subject: [PATCH 63/64] cleaning and adding pyyaml for nosetest --- circle.yml | 105 +++++++++++++++++++++------------------- tests/test_eco_tools.py | 22 --------- 2 files changed, 55 insertions(+), 72 deletions(-) delete mode 100644 tests/test_eco_tools.py diff --git a/circle.yml b/circle.yml index e1b9a89a..24973aed 100644 --- a/circle.yml +++ b/circle.yml @@ -9,19 +9,18 @@ jobs: steps: # Ensure your image has git (required by git to clone via SSH) so that CircleCI can clone your repo - run: apt-get -qq update; apt-get -y install git openssh-client - - run: pip install pyyaml - checkout - run: - name: Build Cymetric - command: | - python ./setup.py install --user + name: Build Cymetric + command: | + python ./setup.py install --user - run: - name: save SHA to a file - command: echo $CIRCLE_SHA1 > .circle-sha + name: save SHA to a file + command: echo $CIRCLE_SHA1 > .circle-sha - save_cache: - key: v1-repo-{{ checksum ".circle-sha" }} - paths: - - /root + key: v1-repo-{{ checksum ".circle-sha" }} + paths: + - /root # Test nosetest: @@ -30,17 +29,19 @@ jobs: working_directory: ~/root steps: - run: - name: save SHA to a file - command: echo $CIRCLE_SHA1 > .circle-sha + name: save SHA to a file + command: echo $CIRCLE_SHA1 > .circle-sha + - run: pip install pyyaml - restore_cache: - keys: - - v1-repo-{{ checksum ".circle-sha" }} + keys: + - v1-repo-{{ checksum ".circle-sha" }} - run: - name: Install nosetest - command: pip install nose + name: Install nosetest + command: pip install nose - run: - name: Nosetests - command: nosetests -w ~/cymetric/tests; exit $? + name: Nosetests + command: nosetests -w ~/cymetric/tests; exit $? + # Update docker container deploy: # Cymetric -> Cymetric:latest @@ -50,19 +51,19 @@ jobs: steps: - checkout - run: - name: Place the proper Dockerfile - command: cp docker/master-ci/Dockerfile . + name: Place the proper Dockerfile + command: cp docker/master-ci/Dockerfile . - setup_remote_docker - run: - name: log into Docker - command: | - docker login -u $DOCKER_USER -p $DOCKER_PASS + name: log into Docker + command: | + docker login -u $DOCKER_USER -p $DOCKER_PASS - run: - name: Build Docker container - command: docker build --rm=false -t cyclus/cymetric:latest . + name: Build Docker container + command: docker build --rm=false -t cyclus/cymetric:latest . - run: - name: Push on DockerHub - command: docker push cyclus/cymetric:latest # push to docker depot + name: Push on DockerHub + command: docker push cyclus/cymetric:latest # push to docker depot deploy_stable: # Cymetric:stable docker: @@ -71,43 +72,47 @@ jobs: steps: - checkout - run: - name: Place the proper Dockerfile - command: cp docker/release-ci/Dockerfile . + name: Place the proper Dockerfile + command: cp docker/release-ci/Dockerfile . - setup_remote_docker - run: - name: Log on DockerHub - command: | - docker login -u $DOCKER_USER -p $DOCKER_PASS + name: Log on DockerHub + command: | + docker login -u $DOCKER_USER -p $DOCKER_PASS - run: - name: Build Docker container - command: docker build -t cyclus/cymetric:stable . + name: Build Docker container + command: docker build -t cyclus/cymetric:stable . - run: - name: Push on DockerHub - command: docker push cyclus/cymetric:stable # push to docker depot + name: Push on DockerHub + command: docker push cyclus/cymetric:stable # push to docker depot + workflows: version: 2 build_and_test: jobs: + # on a pr // all branch - build - nosetest: - requires: - - build + requires: + - build # Merge on Master - deploy: - filters: - branches: - only: master - requires: - - nosetest - # The following should now be done on version tag. + filters: + branches: + only: master + requires: + - nosetest + + + # The following should now be done on version tag. - deploy_stable: - filters: - branches: - ignore: /.*/ - tags: - only: /.*/ - requires: - - nosetest + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + requires: + - nosetest diff --git a/tests/test_eco_tools.py b/tests/test_eco_tools.py deleted file mode 100644 index 3b2dc8bf..00000000 --- a/tests/test_eco_tools.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Tests for functions in eco_tools.py""" -from __future__ import print_function, unicode_literals - -import nose -from nose.tools import assert_equal, assert_less - -import pandas as pd - -from cymetric import evaluator -from cymetric import metrics -from cymetric import root_metrics -from tools import setup, dbtest - - -@dbtest -def test_raw_to_series(db, fname, backend): - df = evaluator.eval('Materials', db) - df2 = evaluator.eval('Resources', db) - assert_equal(isinstance(df2['Quantity'].index, pd.MultiIndex), False) - -if __name__=="__main__": - nose.runmodule() \ No newline at end of file From e2a3208cdfbdc961a3536fe8965f24faa0bf74a6 Mon Sep 17 00:00:00 2001 From: Baptiste Mouginot Date: Fri, 12 Jun 2020 14:22:54 -0500 Subject: [PATCH 64/64] installing pyyaml after cache checkout --- circle.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/circle.yml b/circle.yml index 24973aed..5c83ddfd 100644 --- a/circle.yml +++ b/circle.yml @@ -31,13 +31,12 @@ jobs: - run: name: save SHA to a file command: echo $CIRCLE_SHA1 > .circle-sha - - run: pip install pyyaml - restore_cache: keys: - v1-repo-{{ checksum ".circle-sha" }} - run: name: Install nosetest - command: pip install nose + command: pip install nose pyyaml - run: name: Nosetests command: nosetests -w ~/cymetric/tests; exit $?