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%=31.56945748870393, CC%=40.05506081817221)>,
 <SustainabilityPhaseSummaryResult('Processes', EE%=59.95417367143312, CC%=52.40516764294889)>,
 <SustainabilityPhaseSummaryResult('Transport', EE%=8.476368839862962, CC%=7.539771538878892)>]

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 31.569457 286.103262 40.055061 28.539686
1 Processes 59.954174 543.344296 52.405168 37.339278
2 Transport 8.476369 76.818449 7.539772 5.372173
[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")