Download this example as a Jupyter notebook or a Python script.


Perform a BoM sustainability summary query#

The following supporting files are required for this example:

Run a BoM sustainability summary query#

First, connect to Granta MI.

[1]:
from ansys.grantami.bomanalytics import Connection
[2]:
server_url = "http://my_grantami_server/mi_servicelayer"
cxn = Connection(server_url).with_credentials("user_name", "password").connect()

Next, create a sustainability summary query. The query accepts a single BoM as argument, as well as optional configuration for units. If a unit is not specified, the default unit is used. Default units for the analysis are: MJ for energy, kg for mass, and km for distance.

[3]:
xml_file_path = "supporting-files/bom-2301-assembly.xml"
with open(xml_file_path) as f:
    bom = f.read()

from ansys.grantami.bomanalytics import queries

MASS_UNIT = "kg"
ENERGY_UNIT = "MJ"
DISTANCE_UNIT = "km"

sustainability_summary_query = (
    queries.BomSustainabilitySummaryQuery()
    .with_bom(bom)
    .with_units(mass=MASS_UNIT, energy=ENERGY_UNIT, distance=DISTANCE_UNIT)
)
[4]:
sustainability_summary = cxn.run(sustainability_summary_query)
sustainability_summary
[4]:
<BomSustainabilitySummaryQueryResult>

The BomSustainabilitySummaryQueryResult object returned implements a messages property, and properties showing the environmental impact of the items included in the BoM. Log messages are sorted by decreasing severity. The same messages are available on in the MI Service Layer log file, and are logged via the standard logging module. The next sections show examples of visualizations for the results of the sustainability summary query.

Summary per phase#

The sustainability summary result object contains a phases_summary property. This property summarizes the environmental impact contributions by lifecycle phase: materials, processes, and transport phases. The results for each phase include their absolute and relative contributions to the product as a whole.

[5]:
sustainability_summary.phases_summary
[5]:
[<SustainabilityPhaseSummaryResult('Material', EE%=34.03137120086452, CC%=42.06862708500201)>,
 <SustainabilityPhaseSummaryResult('Processes', EE%=57.886300423973424, CC%=50.720098117450696)>,
 <SustainabilityPhaseSummaryResult('Transport', EE%=8.082328375162053, CC%=7.211274797547294)>]

Use the pandas and plotly libraries to visualize the results. The data will first be translated from the BoM Analytics BomSustainabilitySummaryQueryResult to a pandas Dataframe

[6]:
import pandas as pd

EE_HEADER = f"EE [{ENERGY_UNIT}]"
CC_HEADER = f"CC [{MASS_UNIT}]"

phases_df = pd.DataFrame.from_records(
    [
        {
            "Name": item.name,
            "EE%": item.embodied_energy_percentage,
            EE_HEADER: item.embodied_energy.value,
            "CC%": item.climate_change_percentage,
            CC_HEADER: item.climate_change.value,
        }
        for item in sustainability_summary.phases_summary
    ]
)
phases_df
[6]:
Name EE% EE [MJ] CC% CC [kg]
0 Material 34.031371 323.845810 42.068627 31.595331
1 Processes 57.886300 550.851617 50.720098 38.092954
2 Transport 8.082328 76.912216 7.211275 5.415975
[7]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots


def plot_impact(df, title, textinfo="percent+label", hoverinfo="value+name"):
    fig = make_subplots(
        rows=1,
        cols=2,
        specs=[[{"type": "domain"}, {"type": "domain"}]],
        subplot_titles=["Embodied Energy", "Climate Change"],
    )
    fig.add_trace(go.Pie(labels=df["Name"], values=df[EE_HEADER], name=ENERGY_UNIT), 1, 1)
    fig.add_trace(go.Pie(labels=df["Name"], values=df[CC_HEADER], name=MASS_UNIT), 1, 2)
    fig.update_layout(title_text=title, legend=dict(orientation="h"))
    fig.update_traces(textposition="inside", textinfo=textinfo, hoverinfo=hoverinfo)
    fig.show()


plot_impact(phases_df, "BoM sustainability summary - By phase")