{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# `presamples` tagged graph issue" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Problem\n", "`bw2analyzer.recurse_tagged_database` doesn't work with LCA objects initialised with presamples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Demo\n", "### Import the necessary stuff" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from brightway2 import *" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import presamples as ps" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "from bw2analyzer.tagged import recurse_tagged_database, aggregate_tagged_graph" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Set up the brightway2 project\n", "\n", "> Note - rather than run bw2setup() this takes a library project with ecoinvent 3.3 in it and copies it. \n", "\n", "> To recreate this notebook either do something similar or run bw2setup()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "if 'presamples_test' in projects:\n", " projects.set_current('presamples_test')\n", "else:\n", " projects.set_current('Ecoinvent3_3')\n", " projects.copy_project('presamples_test', switch=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create the simple system\n", "\n", "Below is a picture of the system to be modelled. Basically it's set up so `input_1` has a known climate change impact of `1`, `input_2` has an impact of `2` and `input_3` has an impact of `3`. \n", "\n", "`a`, `b`, and `c` in the diagram are the exchange amounts of each input to `FU`. These all default to `1` (total impact of `6`). \n", "\n", "We're going to try and use `presamples` to run 3 different analyses where only `a`, `b` or `c` is set to `1` (others set to `0` sequentially, so the expected total impacts are `1`, `2` and `3` accordingly." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/presamples_flow_chart.png)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "CO2 = ('biosphere3', 'f9749677-9c9f-4678-ab55-c607dfdc2cb9') # Carbon dioxide, fossil, kg" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "data = {\n", " ('test', 'FU'):{\n", " 'exchanges': [{\n", " 'input':('test', 'input_1'),\n", " 'amount':1,\n", " 'formula':'p_input_1',\n", " 'type': 'technosphere'\n", " },{\n", " 'input':('test', 'input_2'),\n", " 'amount':1,\n", " 'formula':'p_input_2',\n", " 'type': 'technosphere'\n", " },{\n", " 'input':('test', 'input_3'),\n", " 'amount':1,\n", " 'formula':'p_input_3',\n", " 'type': 'technosphere'\n", " },\n", " ],\n", " 'name': 'FU',\n", " 'type': 'process'\n", " },\n", " ('test', 'input_1'):{\n", " 'exchanges': [{\n", " 'amount': 1,\n", " 'input': CO2,\n", " 'type': 'biosphere'\n", " }],\n", " 'name': 'input_1',\n", " 'type': 'process'\n", " },\n", " ('test', 'input_2'):{\n", " 'exchanges': [{\n", " 'amount': 2,\n", " 'input': CO2,\n", " 'type': 'biosphere'\n", " }],\n", " 'name': 'input_2',\n", " 'type': 'process'\n", " },\n", " ('test', 'input_3'):{\n", " 'exchanges': [{\n", " 'amount': 3,\n", " 'input': CO2,\n", " 'type': 'biosphere'\n", " }],\n", " 'name': 'input_3',\n", " 'type': 'process'\n", " }\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create and write the database" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "db = Database(\"test\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Writing activities to SQLite3 database:\n", "0% 100%\n", "[####] | ETA: 00:00:00\n", "Total time elapsed: 00:00:00\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Title: Writing activities to SQLite3 database:\n", " Started: 05/30/2018 15:12:12\n", " Finished: 05/30/2018 15:12:12\n", " Total time elapsed: 00:00:00\n", " CPU %: 97.50\n", " Memory %: 0.81\n" ] } ], "source": [ "db.write(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Define the functional unit and method" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "fu = db.search('FU')[0]" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "m = ('IPCC 2013', 'climate change', 'GTP 100a')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Check the default lca score (expected = `6`)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "lca = LCA({fu:1},m)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "lca.lci()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "lca.lcia()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6.0" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lca.score" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ok that works - next to try it with `presamples`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generate the `presamples` package\n", "\n", "#### Get a list of the inputs to FU" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "FU_inputs = [exc for exc in fu.technosphere()]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Figure out and store the matrix indices" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(('test', 'input_1'), ('test', 'FU'), 'technosphere'),\n", " (('test', 'input_2'), ('test', 'FU'), 'technosphere'),\n", " (('test', 'input_3'), ('test', 'FU'), 'technosphere')]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FU_indices = [(exc['input'], exc['output'], 'technosphere')\n", " for exc in FU_inputs\n", " ]\n", "FU_indices" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Set up the value matrix (3x3 identity matrix)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "one_by_one = np.eye(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Prepare the `presamples` data" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "presamples_one_by_one = [(\n", " one_by_one,\n", " FU_indices,\n", " 'technosphere'\n", ")]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create the `presamples` package" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "test_id, test_fp = ps.create_presamples_package(\n", " matrix_data=presamples_one_by_one,\n", " name='presamples_test_one_by_one',\n", " seed = 'sequential'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Test\n", "\n", "- Set up the LCA\n", "- Run the tagged graph (via `recurse_tagged_database` so we can keep our `LCA` object)\n", "- Aggregate the tagged graph\n", "- Sum the aggregated graph to get the total impact\n", "- compare to `lca.score`" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Run 1: Expected result = 1.0 kg-CO2e\n", "--------------------------------------------\n", "Total impact from LCA score:\t1.0 kg-CO2e\n", "Total impact from graph:\t6.0 kg-CO2e\n", "--------------------------------------------\n", "\n", "Run 2: Expected result = 2.0 kg-CO2e\n", "--------------------------------------------\n", "Total impact from LCA score:\t2.0 kg-CO2e\n", "Total impact from graph:\t6.0 kg-CO2e\n", "--------------------------------------------\n", "\n", "Run 3: Expected result = 3.0 kg-CO2e\n", "--------------------------------------------\n", "Total impact from LCA score:\t3.0 kg-CO2e\n", "Total impact from graph:\t6.0 kg-CO2e\n", "--------------------------------------------\n" ] } ], "source": [ "one_by_one_lca = LCA({fu:1}, m, presamples=[test_fp])\n", "\n", "graphs = []\n", "\n", "for i, k in enumerate(FU_inputs):\n", "\n", " if i==0:\n", " one_by_one_lca.lci()\n", " one_by_one_lca.lcia()\n", " else:\n", " one_by_one_lca.presamples.update_matrices(one_by_one_lca)\n", " one_by_one_lca.redo_lci()\n", " one_by_one_lca.redo_lcia()\n", "\n", " # Note: this is code excised from bw2analyzer.tagged.traverse_tagged_databases\n", " \n", " method_dict = {o[0]: o[1] for o in Method(m).load()}\n", " \n", " label = \"name\" # aggregate on name - i.e. traverse foreground model for contributions\n", " default_tag = \"other\"\n", " \n", " cfu = {fu:1} # change format of fu to include amount\n", " \n", " graph = [recurse_tagged_database(key, amount, method_dict, one_by_one_lca, label, default_tag)\n", " for key, amount in cfu.items()]\n", " \n", " result = aggregate_tagged_graph(graph) # aggregate the tags\n", " \n", " graph_result = sum([v for k, v in result.items()]) # calculate the sum of the impacts\n", " \n", " # print the results\n", " \n", " print(\"\\nRun {}: Expected result = {:.1f} kg-CO2e\\n{}\".format(i+1,i+1, \"-\"*44))\n", " print(\"Total impact from LCA score:\\t{} kg-CO2e\".format(one_by_one_lca.score))\n", " print(\"Total impact from graph:\\t{} kg-CO2e\\n{}\".format(graph_result, \"-\"*44))\n", " \n", " graphs.append(graph) # create a list of the graphs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Result\n", "\n", "`presamples` works as expected for LCA scores, but the tagged graph results reflect the original database\n", "\n", "All of the tagged graphs are the same:" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "graphs[0] == graphs [1] == graphs[2]" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }