From bd1944fce770680a63d49e39612501e4f57801f4 Mon Sep 17 00:00:00 2001 From: TimoDiepers Date: Sat, 4 May 2024 19:02:39 +0200 Subject: [PATCH] clarify some things in the notebooks --- docs/content/examples/example_ev.ipynb | 174 +++++++++++++----- ...mple_simple_dynamic_characterization.ipynb | 102 +++++----- docs/content/theory.rst | 2 +- notebooks/example_setac.ipynb | 174 +++++++++++++----- ...mple_simple_dynamic_characterization.ipynb | 102 +++++----- timex_lca/timex_lca.py | 3 +- 6 files changed, 369 insertions(+), 188 deletions(-) diff --git a/docs/content/examples/example_ev.ipynb b/docs/content/examples/example_ev.ipynb index 22e9a17..e29e3e8 100644 --- a/docs/content/examples/example_ev.ipynb +++ b/docs/content/examples/example_ev.ipynb @@ -24,12 +24,7 @@ "source": [ "import bw2data as bd\n", "\n", - "project_name = \"timex_example_electric_vehicle\"\n", - "if project_name in bd.projects:\n", - " bd.projects.delete_project(project_name)\n", - " bd.projects.purge_deleted_directories()\n", - "\n", - "bd.projects.set_current(project_name)" + "bd.projects.set_current(\"timex_example_electric_vehicle\")" ] }, { @@ -72,8 +67,9 @@ "metadata": {}, "outputs": [], "source": [ + "del bd.databases[\"foreground\"] # to make sure we create the foreground from scratch\n", "foreground = bd.Database(\"foreground\")\n", - "foreground.write({}) # to make sure we start from scratch" + "foreground.write({}) " ] }, { @@ -272,7 +268,7 @@ "output_type": "stream", "text": [ "td_production.date [s]: [-126227808 -94670856 -63113904 -31556952 0]\n", - "td_production.amount [%]: [0. 0.16666667 0.33333333 0.5 0. ]\n" + "td_production.amount [-]: [0. 0.16666667 0.33333333 0.5 0. ]\n" ] }, { @@ -288,7 +284,7 @@ ], "source": [ "print(\"td_production.date [s]: \", td_production.date)\n", - "print(\"td_production.amount [%]:\", td_production.amount)\n", + "print(\"td_production.amount [-]:\", td_production.amount)\n", "type(td_production)" ] }, @@ -407,8 +403,7 @@ "\n", "TimexLCA calculates:\n", " 1) a static LCA score (`TimexLCA.static_lca.score`, same as `bw2calc.lca.score`),\n", - " 2) a static time-explicit LCA score (`TimexLCA.score`), which links LCIs to the respective background databases\n", - " but without additional temporal dynamics of the biosphere flows \n", + " 2) a static time-explicit LCA score (`TimexLCA.score`), which links LCIs to the respective background databases but without additional temporal dynamics of the biosphere flows,\n", " 3) a dynamic time-explicit LCA score (`TimexLCA.dynamic_score`), with dynamic inventory and dynamic charaterization factors. These are provided for radiative forcing and GWP but can also be user-defined.\n", "\n", "Example\n", @@ -425,7 +420,7 @@ ">>> timex_lca.dynamic_lcia(metric=\"radiative_forcing\") # different metrics can be used, e.g. \"GWP\", \"radiative_forcing\"\n", ">>> timex_lca.dynamic_score\n", "\u001b[0;31mInit docstring:\u001b[0m\n", - "Initializes the `TimexLCA` object. Calculates a static LCA, initializes time mapping dicts for activities and biosphere flows, and stores useful subsets of ids in the node_id_collection_dict.\n", + "Instantiating a `TimexLCA` object calculates a static LCA, initializes time mapping dicts for activities and biosphere flows, and stores useful subsets of ids in the node_id_collection_dict.\n", "\n", "Parameters\n", "----------\n", @@ -488,7 +483,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:175: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:182: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", " warnings.warn(\n" ] }, @@ -918,9 +913,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Next, we calculate the LCI.\n", - "\n", - "If we are only interested in the new overall time-explicit scores and don't care about the timing of the emissions, we can set `build_dynamic_biosphere`=`False`, which saves time and memory." + "Next, we calculate the time-explicit LCI. The `TimexLCA.lci()` function takes care of all the relinking, based on the information from the timeline. " ] }, { @@ -936,12 +929,95 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The static results without dynamic characterization:" + "Taking a look at the `dynamic_inventory` that was now created, we can see that it has more rows (emissions) than our usual biosphere3 flows. Instead of one row for each emission in the biosphere database we now get one row for each emission at each point in time." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<51009x72345 sparse matrix of type ''\n", + "\twith 63817 stored elements in Compressed Sparse Row format>" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tlca.dynamic_inventory" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The standard, non-dynamic inventory has far less rows because the temporal resolution is missing. Looking at the timeline again, we see that we have processes at 21 different points in time, which should exactly match the ratio of the dimensions of our two inventories:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<2429x72345 sparse matrix of type ''\n", + "\twith 973421 stored elements in Compressed Sparse Row format>" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tlca.inventory" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "21.0" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tlca.dynamic_inventory.shape[0] / tlca.inventory.shape[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we are only interested in the new overall time-explicit scores and don't care about the timing of the emissions, we can set `build_dynamic_biosphere=False` (default is `True`), which saves time and memory. In that case, you only get the `TimexLCA.inventory`, but not the `TimexLCA.dynamic_inventory`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In case the timing of emissions is not important, one can directly calculate the LCIA the \"standard way\" using static characterization methods. Per default, the following calculates the static lcia score based on the impact method chosen in the very beginning:" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 48, "metadata": {}, "outputs": [ { @@ -950,7 +1026,7 @@ "15697.671861435201" ] }, - "execution_count": 20, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -965,9 +1041,11 @@ "metadata": {}, "source": [ "## Dynamic Characterization\n", - "The time-explicit inventory generated by a `TimexLCA` allow for dynamic characterization. Users can provide their own dynamic characterization functions and link them to corresponding biosphere flows (see example on [dynamic characterization](https://github.com/TimoDiepers/timex/blob/main/notebooks/example_simple_dynamic_characterization.ipynb)), or use the ones we provide out of the box. We provide two different metrics for dynamic LCIA of Climate Change: Radiative forcing [W/m2] and Global Warming Potential (GWP) [kg CO2-eq]. For both of these metrics, we have parameterized dynamic characterization functions for all GHG's that [IPCC AR6](https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-7/) provides data for.\n", + "In addition to the standard static characterization, the time-explicit, dynamic inventory generated by a `TimexLCA` allows for dynamic characterization. Users can provide their own dynamic characterization functions and link them to corresponding biosphere flows (see example on [dynamic characterization](https://github.com/TimoDiepers/timex/blob/main/notebooks/example_simple_dynamic_characterization.ipynb)), or use the ones we provide out of the box. \n", + "\n", + "We provide two different metrics for dynamic LCIA of Climate Change: Radiative forcing [W/m2] and Global Warming Potential (GWP) [kg CO2-eq]. For both of these metrics, we have parameterized dynamic characterization functions for all GHG's that [IPCC AR6](https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-7/) provides data for.\n", "\n", - "For dynamic LCIA metrics, users can select the length of the considered time horizon (`time_horizon`) and whether it is a fixed time horizon (`fixed_time_horizon`). Fixed means that the time horizon for all emissions (no matter when they occur) starts counting at the time of the functional unit, resulting in shorter time horizons for emissions occuring later. If the time horizon is not fixed (this is what conventional impact assessment factors assume), it starts counting from the timing of the emission.\n" + "For the dynamic characterization, users can also choose the length of the considered time horizon (`time_horizon`) and whether it is a fixed time horizon (`fixed_time_horizon`). Fixed means that the time horizon for all emissions (no matter when they occur) starts counting at the time of the functional unit, resulting in shorter time horizons for emissions occuring later. If the time horizon is not fixed (this is what conventional impact assessment factors assume), it starts counting from the timing of the emission.\n" ] }, { @@ -977,6 +1055,13 @@ "### Radiative forcing\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's characterize our dynamic inventory, regarding radiative forcing with a fixed time horizon and the default time horizon length of 100 years:" + ] + }, { "cell_type": "code", "execution_count": 21, @@ -1188,6 +1273,13 @@ "tlca.dynamic_lcia(metric=\"radiative_forcing\", fixed_time_horizon=True)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The method call returns a dataframe of all the individual emissions at their respective timesteps, but we can also just look at the overall score:" + ] + }, { "cell_type": "code", "execution_count": 22, @@ -1212,12 +1304,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Simple plotting functions are available:" + "To visualize the results, we provide a simple plotting functions:" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1244,7 +1336,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 53, "metadata": {}, "outputs": [ { @@ -1266,12 +1358,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Cumulative radiative forcing:" + "There is also a flag to plot the cumulative radiative forcing:" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 54, "metadata": {}, "outputs": [ { @@ -1305,7 +1397,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 55, "metadata": {}, "outputs": [ { @@ -1324,7 +1416,7 @@ "15896.845450102795" ] }, - "execution_count": 26, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1343,7 +1435,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 56, "metadata": {}, "outputs": [ { @@ -1370,7 +1462,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 57, "metadata": {}, "outputs": [ { @@ -1407,7 +1499,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 58, "metadata": {}, "outputs": [ { @@ -1426,7 +1518,7 @@ "15446.54411830293" ] }, - "execution_count": 29, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1445,7 +1537,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 59, "metadata": {}, "outputs": [ { @@ -1454,7 +1546,7 @@ "31401.500705260198" ] }, - "execution_count": 37, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1467,12 +1559,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "However, further down we also want to assess what part of the life cycle has what contribution. To get this info, we need some more calculations:" + "However, further down we also want to look at what part of the life cycle has what contribution. To get this info, we need some more calculations:" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 60, "metadata": {}, "outputs": [], "source": [ @@ -1483,7 +1575,7 @@ " if e.input == ev_lifecycle.key:\n", " continue\n", " lca = bc.LCA({e.input: e.amount}, method)\n", - " lca.lci()\n", + " lca.lci() # one could probably do this more efficiently by using .redo_lcia, but who doesn't like a 15s break :)\n", " lca.lcia()\n", " static_scores[e.input[\"name\"]] = lca.score" ] @@ -1492,12 +1584,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Similarly, we calculate the 2040 (prospective) scores:" + "Similarly, we calculate the 2040 (prospective) scores by just changing the database the exchanges point to:" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 61, "metadata": {}, "outputs": [], "source": [ @@ -1536,7 +1628,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 62, "metadata": {}, "outputs": [ { @@ -1564,7 +1656,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 64, "metadata": {}, "outputs": [ { diff --git a/docs/content/examples/example_simple_dynamic_characterization.ipynb b/docs/content/examples/example_simple_dynamic_characterization.ipynb index 3787b51..28d6026 100644 --- a/docs/content/examples/example_simple_dynamic_characterization.ipynb +++ b/docs/content/examples/example_simple_dynamic_characterization.ipynb @@ -22,7 +22,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1/1 [00:00<00:00, 12985.46it/s]\n" + "100%|██████████| 1/1 [00:00<00:00, 4369.07it/s]\n" ] }, { @@ -37,7 +37,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1/1 [00:00<00:00, 18808.54it/s]" + "100%|██████████| 1/1 [00:00<00:00, 17189.77it/s]" ] }, { @@ -62,7 +62,7 @@ "\n", "project_name = \"timex_example_dynamic_characterization\"\n", "if project_name in bd.projects:\n", - " bd.projects.delete_project(project_name)\n", + " bd.projects.delete_project(project_name) # making sure to start from scratch\n", " bd.projects.purge_deleted_directories()\n", "\n", "bd.projects.set_current(project_name)\n", @@ -120,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "8d9405d9", "metadata": {}, "outputs": [], @@ -131,10 +131,19 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "71bba776", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:100: UserWarning: No database_date_dict provided. Treating the databases containing the functional unit as dynamic. No remapping to time explicit databases will be done.\n", + " warnings.warn(\n" + ] + } + ], "source": [ "from timex_lca import TimexLCA\n", "\n", @@ -143,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "c40754e8", "metadata": {}, "outputs": [ @@ -158,7 +167,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:175: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:182: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", " warnings.warn(\n", "/Users/timodiepers/Documents/Coding/timex/timex_lca/timeline_builder.py:191: Warning: No time-explicit databases are provided. Mapping to time-explicit databases is not possible.\n", " warnings.warn(\n" @@ -215,7 +224,7 @@ "0 None " ] }, - "execution_count": 6, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -256,21 +265,14 @@ "tlca.static_score" ] }, - { - "cell_type": "markdown", - "id": "b961cf1e", - "metadata": {}, - "source": [ - "## Dynamic characterization\n" - ] - }, { "cell_type": "markdown", "id": "8729dc9f", "metadata": {}, "source": [ - "While users can profile their own dynamic LCIA methods, `timex_lca` has implemenented default dynamic characterization functions for 2 climate change metrics, based on IPCC AR6:\n", + "## Dynamic characterization\n", "\n", + "While users can profile their own dynamic LCIA methods, `timex_lca` has implemenented default dynamic characterization functions for 2 climate change metrics, based on IPCC AR6:\n", "- radiative forcing [W/m2]\n", "- Global warming potential (GWP) [kg CO2eq],\n", "\n", @@ -291,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "b86341cc", "metadata": {}, "outputs": [ @@ -330,15 +332,11 @@ "- flow: str\n", "- activity: str\n", "\n", - "Notes\n", - "-----\n", - "See also the relevant scientific publication on CRF: https://doi.org/10.5194/acp-13-2793-2013\n", - "See also the relevant scientific publication on the numerical calculation of CRF: http://pubs.acs.org/doi/abs/10.1021/acs.est.5b01118\n", - "See also the IPCC AR6 Chapter 7 (Table 7.15) for the updated numerical values: https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_Chapter07.pdf\n", - "\n", - "See Also\n", + "See also\n", "--------\n", - "characterize_co2: The same function for CO2\n", + "Joos2013: Relevant scientific publication on CRF: https://doi.org/10.5194/acp-13-2793-2013\n", + "Schivley2015: Relevant scientific publication on the numerical calculation of CRF: https://doi.org/10.1021/acs.est.5b01118\n", + "Forster2023: Updated numerical values from IPCC AR6 Chapter 7 (Table 7.15): https://doi.org/10.1017/9781009157896.009\n", "\u001b[0;31mFile:\u001b[0m ~/Documents/Coding/timex/timex_lca/dynamic_characterization.py\n", "\u001b[0;31mType:\u001b[0m function" ] @@ -360,7 +358,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "c01ea15d", "metadata": {}, "outputs": [], @@ -380,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "246683b4", "metadata": {}, "outputs": [ @@ -560,7 +558,7 @@ "[99 rows x 7 columns]" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -575,7 +573,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "5868fb38", "metadata": {}, "outputs": [ @@ -604,7 +602,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "40c30c15", "metadata": {}, "outputs": [ @@ -632,7 +630,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "7fdfc3c7", "metadata": {}, "outputs": [ @@ -667,7 +665,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "bc445e2a", "metadata": {}, "outputs": [ @@ -758,7 +756,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "id": "d66dd743", "metadata": {}, "outputs": [ @@ -800,7 +798,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "eecd5073", "metadata": {}, "outputs": [ @@ -845,7 +843,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "id": "e075e0f9", "metadata": {}, "outputs": [], @@ -936,7 +934,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "15b6f25d", "metadata": {}, "outputs": [ @@ -944,7 +942,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 3/3 [00:00<00:00, 50942.96it/s]\n" + "100%|██████████| 3/3 [00:00<00:00, 46091.25it/s]\n" ] }, { @@ -959,7 +957,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1/1 [00:00<00:00, 22671.91it/s]" + "100%|██████████| 1/1 [00:00<00:00, 25420.02it/s]" ] }, { @@ -991,7 +989,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "6ef97c64", "metadata": {}, "outputs": [ @@ -1006,9 +1004,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:101: UserWarning: No database_date_dict provided. Treating the databases containing the functional unit as dynamic. No remapping to time explicit databases will be done.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:100: UserWarning: No database_date_dict provided. Treating the databases containing the functional unit as dynamic. No remapping to time explicit databases will be done.\n", " warnings.warn(\n", - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:175: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:182: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", " warnings.warn(\n", "/Users/timodiepers/Documents/Coding/timex/timex_lca/timeline_builder.py:191: Warning: No time-explicit databases are provided. Mapping to time-explicit databases is not possible.\n", " warnings.warn(\n" @@ -1037,7 +1035,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "id": "f6ff1eb3", "metadata": {}, "outputs": [], @@ -1059,7 +1057,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "id": "e3b6c6b4", "metadata": {}, "outputs": [ @@ -1096,7 +1094,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, "id": "4668245f", "metadata": {}, "outputs": [ @@ -1125,7 +1123,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 26, "id": "9cae721c", "metadata": {}, "outputs": [ @@ -1235,22 +1233,22 @@ "gwp_flexible_TH = {}\n", "gwp_fixed_TH = {}\n", "\n", - "for i in range(20, 110, 10): # 20 to 100 TH in steps of 10 years\n", + "for time_horizon in range(20, 110, 10): # 20 to 100 TH in steps of 10 years\n", " tlca.dynamic_lcia(\n", " metric=\"GWP\",\n", - " time_horizon=i,\n", + " time_horizon=time_horizon,\n", " fixed_time_horizon=True,\n", " characterization_function_dict=characterization_function_dict,\n", " )\n", - " gwp_fixed_TH[i] = tlca.dynamic_score\n", + " gwp_fixed_TH[time_horizon] = tlca.dynamic_score\n", "\n", " tlca.dynamic_lcia(\n", " metric=\"GWP\",\n", - " time_horizon=i,\n", + " time_horizon=time_horizon,\n", " fixed_time_horizon=False,\n", " characterization_function_dict=characterization_function_dict,\n", " )\n", - " gwp_flexible_TH[i] = tlca.dynamic_score\n", + " gwp_flexible_TH[time_horizon] = tlca.dynamic_score\n", "\n", "# add values for 500 years:\n", "tlca.dynamic_lcia(\n", diff --git a/docs/content/theory.rst b/docs/content/theory.rst index 1eeb259..1549d2e 100644 --- a/docs/content/theory.rst +++ b/docs/content/theory.rst @@ -103,7 +103,7 @@ Depending on the user's choice, two different biosphere matrices are created: Static or dynamic impact assessment ----------------------------------- -``timex_lca`` allows to use conventional static impact assessment methods, which are executed using ``TimexLCA.lcia()``. +``timex_lca`` allows to use conventional static impact assessment methods, which are executed using ``TimexLCA.static_lcia()``. To take advantage of the detailed temporal information at the inventory level, dynamic LCIA can be applied, using ``TimexLCA.dynamic_lcia()``. Users can define or import their own dynamic LCIA functions. Out of the box, we provide dynamic LCIA functions for the climate change metrics 'radiative forcing' and 'global warming potential (GWP)' for all greenhouse gases in the `IPCC AR6 report Chapter 7 Table 7.SM.7 `_. diff --git a/notebooks/example_setac.ipynb b/notebooks/example_setac.ipynb index 22e9a17..e29e3e8 100644 --- a/notebooks/example_setac.ipynb +++ b/notebooks/example_setac.ipynb @@ -24,12 +24,7 @@ "source": [ "import bw2data as bd\n", "\n", - "project_name = \"timex_example_electric_vehicle\"\n", - "if project_name in bd.projects:\n", - " bd.projects.delete_project(project_name)\n", - " bd.projects.purge_deleted_directories()\n", - "\n", - "bd.projects.set_current(project_name)" + "bd.projects.set_current(\"timex_example_electric_vehicle\")" ] }, { @@ -72,8 +67,9 @@ "metadata": {}, "outputs": [], "source": [ + "del bd.databases[\"foreground\"] # to make sure we create the foreground from scratch\n", "foreground = bd.Database(\"foreground\")\n", - "foreground.write({}) # to make sure we start from scratch" + "foreground.write({}) " ] }, { @@ -272,7 +268,7 @@ "output_type": "stream", "text": [ "td_production.date [s]: [-126227808 -94670856 -63113904 -31556952 0]\n", - "td_production.amount [%]: [0. 0.16666667 0.33333333 0.5 0. ]\n" + "td_production.amount [-]: [0. 0.16666667 0.33333333 0.5 0. ]\n" ] }, { @@ -288,7 +284,7 @@ ], "source": [ "print(\"td_production.date [s]: \", td_production.date)\n", - "print(\"td_production.amount [%]:\", td_production.amount)\n", + "print(\"td_production.amount [-]:\", td_production.amount)\n", "type(td_production)" ] }, @@ -407,8 +403,7 @@ "\n", "TimexLCA calculates:\n", " 1) a static LCA score (`TimexLCA.static_lca.score`, same as `bw2calc.lca.score`),\n", - " 2) a static time-explicit LCA score (`TimexLCA.score`), which links LCIs to the respective background databases\n", - " but without additional temporal dynamics of the biosphere flows \n", + " 2) a static time-explicit LCA score (`TimexLCA.score`), which links LCIs to the respective background databases but without additional temporal dynamics of the biosphere flows,\n", " 3) a dynamic time-explicit LCA score (`TimexLCA.dynamic_score`), with dynamic inventory and dynamic charaterization factors. These are provided for radiative forcing and GWP but can also be user-defined.\n", "\n", "Example\n", @@ -425,7 +420,7 @@ ">>> timex_lca.dynamic_lcia(metric=\"radiative_forcing\") # different metrics can be used, e.g. \"GWP\", \"radiative_forcing\"\n", ">>> timex_lca.dynamic_score\n", "\u001b[0;31mInit docstring:\u001b[0m\n", - "Initializes the `TimexLCA` object. Calculates a static LCA, initializes time mapping dicts for activities and biosphere flows, and stores useful subsets of ids in the node_id_collection_dict.\n", + "Instantiating a `TimexLCA` object calculates a static LCA, initializes time mapping dicts for activities and biosphere flows, and stores useful subsets of ids in the node_id_collection_dict.\n", "\n", "Parameters\n", "----------\n", @@ -488,7 +483,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:175: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:182: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", " warnings.warn(\n" ] }, @@ -918,9 +913,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Next, we calculate the LCI.\n", - "\n", - "If we are only interested in the new overall time-explicit scores and don't care about the timing of the emissions, we can set `build_dynamic_biosphere`=`False`, which saves time and memory." + "Next, we calculate the time-explicit LCI. The `TimexLCA.lci()` function takes care of all the relinking, based on the information from the timeline. " ] }, { @@ -936,12 +929,95 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The static results without dynamic characterization:" + "Taking a look at the `dynamic_inventory` that was now created, we can see that it has more rows (emissions) than our usual biosphere3 flows. Instead of one row for each emission in the biosphere database we now get one row for each emission at each point in time." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<51009x72345 sparse matrix of type ''\n", + "\twith 63817 stored elements in Compressed Sparse Row format>" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tlca.dynamic_inventory" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The standard, non-dynamic inventory has far less rows because the temporal resolution is missing. Looking at the timeline again, we see that we have processes at 21 different points in time, which should exactly match the ratio of the dimensions of our two inventories:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<2429x72345 sparse matrix of type ''\n", + "\twith 973421 stored elements in Compressed Sparse Row format>" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tlca.inventory" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "21.0" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tlca.dynamic_inventory.shape[0] / tlca.inventory.shape[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we are only interested in the new overall time-explicit scores and don't care about the timing of the emissions, we can set `build_dynamic_biosphere=False` (default is `True`), which saves time and memory. In that case, you only get the `TimexLCA.inventory`, but not the `TimexLCA.dynamic_inventory`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In case the timing of emissions is not important, one can directly calculate the LCIA the \"standard way\" using static characterization methods. Per default, the following calculates the static lcia score based on the impact method chosen in the very beginning:" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 48, "metadata": {}, "outputs": [ { @@ -950,7 +1026,7 @@ "15697.671861435201" ] }, - "execution_count": 20, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -965,9 +1041,11 @@ "metadata": {}, "source": [ "## Dynamic Characterization\n", - "The time-explicit inventory generated by a `TimexLCA` allow for dynamic characterization. Users can provide their own dynamic characterization functions and link them to corresponding biosphere flows (see example on [dynamic characterization](https://github.com/TimoDiepers/timex/blob/main/notebooks/example_simple_dynamic_characterization.ipynb)), or use the ones we provide out of the box. We provide two different metrics for dynamic LCIA of Climate Change: Radiative forcing [W/m2] and Global Warming Potential (GWP) [kg CO2-eq]. For both of these metrics, we have parameterized dynamic characterization functions for all GHG's that [IPCC AR6](https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-7/) provides data for.\n", + "In addition to the standard static characterization, the time-explicit, dynamic inventory generated by a `TimexLCA` allows for dynamic characterization. Users can provide their own dynamic characterization functions and link them to corresponding biosphere flows (see example on [dynamic characterization](https://github.com/TimoDiepers/timex/blob/main/notebooks/example_simple_dynamic_characterization.ipynb)), or use the ones we provide out of the box. \n", + "\n", + "We provide two different metrics for dynamic LCIA of Climate Change: Radiative forcing [W/m2] and Global Warming Potential (GWP) [kg CO2-eq]. For both of these metrics, we have parameterized dynamic characterization functions for all GHG's that [IPCC AR6](https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-7/) provides data for.\n", "\n", - "For dynamic LCIA metrics, users can select the length of the considered time horizon (`time_horizon`) and whether it is a fixed time horizon (`fixed_time_horizon`). Fixed means that the time horizon for all emissions (no matter when they occur) starts counting at the time of the functional unit, resulting in shorter time horizons for emissions occuring later. If the time horizon is not fixed (this is what conventional impact assessment factors assume), it starts counting from the timing of the emission.\n" + "For the dynamic characterization, users can also choose the length of the considered time horizon (`time_horizon`) and whether it is a fixed time horizon (`fixed_time_horizon`). Fixed means that the time horizon for all emissions (no matter when they occur) starts counting at the time of the functional unit, resulting in shorter time horizons for emissions occuring later. If the time horizon is not fixed (this is what conventional impact assessment factors assume), it starts counting from the timing of the emission.\n" ] }, { @@ -977,6 +1055,13 @@ "### Radiative forcing\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's characterize our dynamic inventory, regarding radiative forcing with a fixed time horizon and the default time horizon length of 100 years:" + ] + }, { "cell_type": "code", "execution_count": 21, @@ -1188,6 +1273,13 @@ "tlca.dynamic_lcia(metric=\"radiative_forcing\", fixed_time_horizon=True)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The method call returns a dataframe of all the individual emissions at their respective timesteps, but we can also just look at the overall score:" + ] + }, { "cell_type": "code", "execution_count": 22, @@ -1212,12 +1304,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Simple plotting functions are available:" + "To visualize the results, we provide a simple plotting functions:" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1244,7 +1336,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 53, "metadata": {}, "outputs": [ { @@ -1266,12 +1358,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Cumulative radiative forcing:" + "There is also a flag to plot the cumulative radiative forcing:" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 54, "metadata": {}, "outputs": [ { @@ -1305,7 +1397,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 55, "metadata": {}, "outputs": [ { @@ -1324,7 +1416,7 @@ "15896.845450102795" ] }, - "execution_count": 26, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1343,7 +1435,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 56, "metadata": {}, "outputs": [ { @@ -1370,7 +1462,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 57, "metadata": {}, "outputs": [ { @@ -1407,7 +1499,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 58, "metadata": {}, "outputs": [ { @@ -1426,7 +1518,7 @@ "15446.54411830293" ] }, - "execution_count": 29, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1445,7 +1537,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 59, "metadata": {}, "outputs": [ { @@ -1454,7 +1546,7 @@ "31401.500705260198" ] }, - "execution_count": 37, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1467,12 +1559,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "However, further down we also want to assess what part of the life cycle has what contribution. To get this info, we need some more calculations:" + "However, further down we also want to look at what part of the life cycle has what contribution. To get this info, we need some more calculations:" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 60, "metadata": {}, "outputs": [], "source": [ @@ -1483,7 +1575,7 @@ " if e.input == ev_lifecycle.key:\n", " continue\n", " lca = bc.LCA({e.input: e.amount}, method)\n", - " lca.lci()\n", + " lca.lci() # one could probably do this more efficiently by using .redo_lcia, but who doesn't like a 15s break :)\n", " lca.lcia()\n", " static_scores[e.input[\"name\"]] = lca.score" ] @@ -1492,12 +1584,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Similarly, we calculate the 2040 (prospective) scores:" + "Similarly, we calculate the 2040 (prospective) scores by just changing the database the exchanges point to:" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 61, "metadata": {}, "outputs": [], "source": [ @@ -1536,7 +1628,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 62, "metadata": {}, "outputs": [ { @@ -1564,7 +1656,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 64, "metadata": {}, "outputs": [ { diff --git a/notebooks/example_simple_dynamic_characterization.ipynb b/notebooks/example_simple_dynamic_characterization.ipynb index 3787b51..28d6026 100644 --- a/notebooks/example_simple_dynamic_characterization.ipynb +++ b/notebooks/example_simple_dynamic_characterization.ipynb @@ -22,7 +22,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1/1 [00:00<00:00, 12985.46it/s]\n" + "100%|██████████| 1/1 [00:00<00:00, 4369.07it/s]\n" ] }, { @@ -37,7 +37,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1/1 [00:00<00:00, 18808.54it/s]" + "100%|██████████| 1/1 [00:00<00:00, 17189.77it/s]" ] }, { @@ -62,7 +62,7 @@ "\n", "project_name = \"timex_example_dynamic_characterization\"\n", "if project_name in bd.projects:\n", - " bd.projects.delete_project(project_name)\n", + " bd.projects.delete_project(project_name) # making sure to start from scratch\n", " bd.projects.purge_deleted_directories()\n", "\n", "bd.projects.set_current(project_name)\n", @@ -120,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "8d9405d9", "metadata": {}, "outputs": [], @@ -131,10 +131,19 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "71bba776", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:100: UserWarning: No database_date_dict provided. Treating the databases containing the functional unit as dynamic. No remapping to time explicit databases will be done.\n", + " warnings.warn(\n" + ] + } + ], "source": [ "from timex_lca import TimexLCA\n", "\n", @@ -143,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "c40754e8", "metadata": {}, "outputs": [ @@ -158,7 +167,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:175: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:182: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", " warnings.warn(\n", "/Users/timodiepers/Documents/Coding/timex/timex_lca/timeline_builder.py:191: Warning: No time-explicit databases are provided. Mapping to time-explicit databases is not possible.\n", " warnings.warn(\n" @@ -215,7 +224,7 @@ "0 None " ] }, - "execution_count": 6, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -256,21 +265,14 @@ "tlca.static_score" ] }, - { - "cell_type": "markdown", - "id": "b961cf1e", - "metadata": {}, - "source": [ - "## Dynamic characterization\n" - ] - }, { "cell_type": "markdown", "id": "8729dc9f", "metadata": {}, "source": [ - "While users can profile their own dynamic LCIA methods, `timex_lca` has implemenented default dynamic characterization functions for 2 climate change metrics, based on IPCC AR6:\n", + "## Dynamic characterization\n", "\n", + "While users can profile their own dynamic LCIA methods, `timex_lca` has implemenented default dynamic characterization functions for 2 climate change metrics, based on IPCC AR6:\n", "- radiative forcing [W/m2]\n", "- Global warming potential (GWP) [kg CO2eq],\n", "\n", @@ -291,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "b86341cc", "metadata": {}, "outputs": [ @@ -330,15 +332,11 @@ "- flow: str\n", "- activity: str\n", "\n", - "Notes\n", - "-----\n", - "See also the relevant scientific publication on CRF: https://doi.org/10.5194/acp-13-2793-2013\n", - "See also the relevant scientific publication on the numerical calculation of CRF: http://pubs.acs.org/doi/abs/10.1021/acs.est.5b01118\n", - "See also the IPCC AR6 Chapter 7 (Table 7.15) for the updated numerical values: https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_Chapter07.pdf\n", - "\n", - "See Also\n", + "See also\n", "--------\n", - "characterize_co2: The same function for CO2\n", + "Joos2013: Relevant scientific publication on CRF: https://doi.org/10.5194/acp-13-2793-2013\n", + "Schivley2015: Relevant scientific publication on the numerical calculation of CRF: https://doi.org/10.1021/acs.est.5b01118\n", + "Forster2023: Updated numerical values from IPCC AR6 Chapter 7 (Table 7.15): https://doi.org/10.1017/9781009157896.009\n", "\u001b[0;31mFile:\u001b[0m ~/Documents/Coding/timex/timex_lca/dynamic_characterization.py\n", "\u001b[0;31mType:\u001b[0m function" ] @@ -360,7 +358,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "c01ea15d", "metadata": {}, "outputs": [], @@ -380,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "246683b4", "metadata": {}, "outputs": [ @@ -560,7 +558,7 @@ "[99 rows x 7 columns]" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -575,7 +573,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "5868fb38", "metadata": {}, "outputs": [ @@ -604,7 +602,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "40c30c15", "metadata": {}, "outputs": [ @@ -632,7 +630,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "7fdfc3c7", "metadata": {}, "outputs": [ @@ -667,7 +665,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "bc445e2a", "metadata": {}, "outputs": [ @@ -758,7 +756,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "id": "d66dd743", "metadata": {}, "outputs": [ @@ -800,7 +798,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "eecd5073", "metadata": {}, "outputs": [ @@ -845,7 +843,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "id": "e075e0f9", "metadata": {}, "outputs": [], @@ -936,7 +934,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "15b6f25d", "metadata": {}, "outputs": [ @@ -944,7 +942,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 3/3 [00:00<00:00, 50942.96it/s]\n" + "100%|██████████| 3/3 [00:00<00:00, 46091.25it/s]\n" ] }, { @@ -959,7 +957,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1/1 [00:00<00:00, 22671.91it/s]" + "100%|██████████| 1/1 [00:00<00:00, 25420.02it/s]" ] }, { @@ -991,7 +989,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "6ef97c64", "metadata": {}, "outputs": [ @@ -1006,9 +1004,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:101: UserWarning: No database_date_dict provided. Treating the databases containing the functional unit as dynamic. No remapping to time explicit databases will be done.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:100: UserWarning: No database_date_dict provided. Treating the databases containing the functional unit as dynamic. No remapping to time explicit databases will be done.\n", " warnings.warn(\n", - "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:175: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", + "/Users/timodiepers/Documents/Coding/timex/timex_lca/timex_lca.py:182: UserWarning: No edge filter function provided. Skipping all edges within background databases.\n", " warnings.warn(\n", "/Users/timodiepers/Documents/Coding/timex/timex_lca/timeline_builder.py:191: Warning: No time-explicit databases are provided. Mapping to time-explicit databases is not possible.\n", " warnings.warn(\n" @@ -1037,7 +1035,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "id": "f6ff1eb3", "metadata": {}, "outputs": [], @@ -1059,7 +1057,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "id": "e3b6c6b4", "metadata": {}, "outputs": [ @@ -1096,7 +1094,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, "id": "4668245f", "metadata": {}, "outputs": [ @@ -1125,7 +1123,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 26, "id": "9cae721c", "metadata": {}, "outputs": [ @@ -1235,22 +1233,22 @@ "gwp_flexible_TH = {}\n", "gwp_fixed_TH = {}\n", "\n", - "for i in range(20, 110, 10): # 20 to 100 TH in steps of 10 years\n", + "for time_horizon in range(20, 110, 10): # 20 to 100 TH in steps of 10 years\n", " tlca.dynamic_lcia(\n", " metric=\"GWP\",\n", - " time_horizon=i,\n", + " time_horizon=time_horizon,\n", " fixed_time_horizon=True,\n", " characterization_function_dict=characterization_function_dict,\n", " )\n", - " gwp_fixed_TH[i] = tlca.dynamic_score\n", + " gwp_fixed_TH[time_horizon] = tlca.dynamic_score\n", "\n", " tlca.dynamic_lcia(\n", " metric=\"GWP\",\n", - " time_horizon=i,\n", + " time_horizon=time_horizon,\n", " fixed_time_horizon=False,\n", " characterization_function_dict=characterization_function_dict,\n", " )\n", - " gwp_flexible_TH[i] = tlca.dynamic_score\n", + " gwp_flexible_TH[time_horizon] = tlca.dynamic_score\n", "\n", "# add values for 500 years:\n", "tlca.dynamic_lcia(\n", diff --git a/timex_lca/timex_lca.py b/timex_lca/timex_lca.py index 83b7d3d..67cb855 100644 --- a/timex_lca/timex_lca.py +++ b/timex_lca/timex_lca.py @@ -226,7 +226,8 @@ def lci(self, build_dynamic_biosphere: Optional[bool] = True) -> None: """ Calculates the time-explicit LCI. - Generates the biosphere and technosphere modifications via the `MatrixModifier` class by calling `TimexLCA.build_datapackage()`. Optionally, the dynamic biosphere matrix and dynamic inventory is calculated via + Generates the biosphere and technosphere modifications via the `MatrixModifier` class by calling `TimexLCA. + build_datapackage()`. Optionally, the dynamic biosphere matrix and dynamic inventory is calculated via `TimexLCA.calculate_dynamic_inventory()`. Set `build_dynamic_biosphere` to False if you only want to get a new overall score and don't care about the timing of the emissions. This saves time and memory.