{ "cells": [ { "cell_type": "markdown", "id": "cd1e0860", "metadata": {}, "source": [ "# Messages and phase summary\n", "\n", "This example shows how to run a sustainability summary query and how to explore the phases summary result. It also\n", "shows how to review any messages generated by the server during the analysis.\n", "\n", "The following supporting files are required for this example:\n", "\n", "* [sustainability-bom-2412.xml](../supporting-files/sustainability-bom-2412.xml)\n", "\n", "For help on constructing an XML BoM, see [BoM examples](../6_BoMs/index.rst)." ] }, { "cell_type": "markdown", "id": "2806a02a", "metadata": {}, "source": [ "
\n", "\n", "**Info:**\n", "\n", "This example uses an input file that is in the 24/12 XML BoM format. This structure requires Granta MI Restricted\n", "Substances and Sustainability Reports 2025 R2 or later.\n", "\n", "To run this example with an older version of the reports bundle, use\n", "[sustainability-bom-2301.xml](../supporting-files/sustainability-bom-2301.xml) instead. Some sections of this example\n", "will produce different results from the published example when this BoM is used.\n", "
" ] }, { "cell_type": "markdown", "id": "629a04be", "metadata": {}, "source": [ "## Run a sustainability summary query\n", "\n", "First, connect to Granta MI.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "1864564f", "metadata": {}, "outputs": [], "source": [ "from ansys.grantami.bomanalytics import Connection\n", "\n", "server_url = \"http://my_grantami_server/mi_servicelayer\"\n", "cxn = Connection(server_url).with_credentials(\"user_name\", \"password\").connect()" ] }, { "cell_type": "markdown", "id": "3d1c73f1", "metadata": {}, "source": [ "Next, create a sustainability summary query. The query accepts a single BoM as argument and an optional\n", "configuration for units. If a unit is not specified, the default unit is used. Default units for the analysis are\n", "``MJ`` for energy, ``kg`` for mass, and ``km`` for distance." ] }, { "cell_type": "code", "execution_count": null, "id": "069fae56", "metadata": {}, "outputs": [], "source": [ "xml_file_path = \"../supporting-files/sustainability-bom-2412.xml\"\n", "with open(xml_file_path) as f:\n", " bom = f.read()\n", "\n", "from ansys.grantami.bomanalytics import queries\n", "\n", "MASS_UNIT = \"kg\"\n", "ENERGY_UNIT = \"MJ\"\n", "DISTANCE_UNIT = \"km\"\n", "\n", "sustainability_summary_query = (\n", " queries.BomSustainabilitySummaryQuery()\n", " .with_bom(bom)\n", " .with_units(mass=MASS_UNIT, energy=ENERGY_UNIT, distance=DISTANCE_UNIT)\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "4a06af7f", "metadata": {}, "outputs": [], "source": [ "sustainability_summary = cxn.run(sustainability_summary_query)\n", "sustainability_summary" ] }, { "cell_type": "markdown", "id": "a425c7e1", "metadata": {}, "source": [ "## Messages\n", "\n", "The ``BomSustainabilitySummaryQueryResult`` object that is returned implements a ``messages`` property and properties\n", "showing the environmental impact of the items included in the BoM.\n", "Log messages are sorted by decreasing severity. The same messages are available in the MI Service Layer log file\n", "and are logged using the standard ``logging`` module.\n", "\n", "If there are no messages, an empty list is returned. This means there were no unexpected events during BoM analysis." ] }, { "cell_type": "code", "execution_count": null, "id": "d79266a9", "metadata": {}, "outputs": [], "source": [ "sustainability_summary.messages" ] }, { "cell_type": "markdown", "id": "69310a5b", "metadata": {}, "source": [ "## Phases summary\n", "\n", "The ``phases_summary`` property summarizes the environmental impact contributions by lifecycle phase: materials,\n", "processes, and transport phases. The results for each phase include their absolute and relative contributions to\n", "the product as a whole." ] }, { "cell_type": "code", "execution_count": null, "id": "944eaf99", "metadata": {}, "outputs": [], "source": [ "sustainability_summary.phases_summary" ] }, { "cell_type": "markdown", "id": "539075a2", "metadata": {}, "source": [ "Use the [pandas](https://pandas.pydata.org/) and [plotly](https://plotly.com/python/) libraries to visualize the\n", "results. First, the data is translated from the BoM Analytics ``BomSustainabilitySummaryQueryResult`` to a pandas\n", "``Dataframe`` object." ] }, { "cell_type": "code", "execution_count": null, "id": "e39ea374", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "EE_HEADER = f\"EE [{ENERGY_UNIT}]\"\n", "CC_HEADER = f\"CC [{MASS_UNIT}]\"\n", "\n", "phases_df = pd.DataFrame.from_records(\n", " [\n", " {\n", " \"Name\": item.name,\n", " \"EE%\": item.embodied_energy_percentage,\n", " EE_HEADER: item.embodied_energy.value,\n", " \"CC%\": item.climate_change_percentage,\n", " CC_HEADER: item.climate_change.value,\n", " }\n", " for item in sustainability_summary.phases_summary\n", " ]\n", ")\n", "phases_df" ] }, { "cell_type": "markdown", "id": "9994711e", "metadata": {}, "source": [ "Next, the dataframe is visualized as a pair of pie charts." ] }, { "cell_type": "code", "execution_count": null, "id": "2b224ee8", "metadata": {}, "outputs": [], "source": [ "import plotly.graph_objects as go\n", "from plotly.subplots import make_subplots\n", "\n", "fig = make_subplots(\n", " rows=1,\n", " cols=2,\n", " specs=[[{\"type\": \"domain\"}, {\"type\": \"domain\"}]],\n", " subplot_titles=[\"Embodied Energy\", \"Climate Change\"],\n", " )\n", "fig.add_trace(go.Pie(labels=phases_df[\"Name\"], values=phases_df[EE_HEADER], name=ENERGY_UNIT), 1, 1)\n", "fig.add_trace(go.Pie(labels=phases_df[\"Name\"], values=phases_df[CC_HEADER], name=MASS_UNIT), 1, 2)\n", "fig.update_layout(title_text=\"BoM sustainability summary - By phase\", legend=dict(orientation=\"h\"))\n", "fig.update_traces(textposition=\"inside\", textinfo=\"percent+label\", hoverinfo=\"value+name\")\n", "fig.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }