Get Results workflow#

This example shows how to use PyConcentEV to get a list of result parameters from a list of design_instance_ids These lists are provided in design_instance_ids.csv

Warning

Assumes a front and rear motor architecture. Assumes a specific drive cycle result is available. If short results is true it gets in User Units Assumes first job in list for each project is the result we want.

Perform required imports#

Get the necessary imports.

import datetime
import json
import time

import matplotlib.pyplot as plt
import pandas as pd

from ansys.conceptev.core import app
from ansys.conceptev.core.settings import settings

OCM_URL = settings.ocm_url

Inputs#

Change the following variables to match your data.

short_results = True  # For results created after 15/11/2024 improved performance.
get_results_off_server = True  # Generates an output file that can be read later.
output_filename = "results.xlsx"  # Output filename for results.

Generate and run templates#

This function generates a new project and runs a template for each design_instance_id The design_instance_ids are returned for later use.

def generate_and_run_templates(client, account_id, hpc_id):
    token = app.get_token(client)
    project_id = app.create_new_project(
        client, account_id, hpc_id, f"New Project {datetime.datetime.now()}"
    )
    template_ids = ["ae7ca4d7-4bac-48f5-be42-d5f0b6a24b00"]
    design_instance_ids = []
    for template_id in template_ids:
        design_instance_id = app.create_design_instance(
            project_id["projectId"], f"New Concept {datetime.datetime.now()}", token
        )
        concept = app.copy_concept(template_id, design_instance_id, client)
        job_info = app.create_submit_job(
            client,
            concept,
            account_id,
            hpc_id,
            job_name=f"cli_job: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')}",
        )
        design_instance_ids.append(design_instance_id)
    return design_instance_ids

Create a client and set up projects#

Gets the account_id and hpc_id Generates and runs templates

with app.get_http_client() as client:
    token = app.get_token(client)
    account_id = app.get_account_id(token)
    hpc_id = app.get_default_hpc(token, account_id)
    design_instance_ids = generate_and_run_templates(client, account_id, hpc_id)
Encryption unavailable. Opting in to plain text.
Traceback (most recent call last):
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/libsecret.py", line 18, in <module>
    import gi  # https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/Encryption-on-Linux  # pylint: disable=line-too-long
    ^^^^^^^^^
ModuleNotFoundError: No module named 'gi'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/pyconceptev/pyconceptev/src/ansys/conceptev/core/auth.py", line 53, in build_persistence
    return build_encrypted_persistence(location)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/persistence.py", line 98, in build_encrypted_persistence
    return LibsecretPersistence(location)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/persistence.py", line 314, in __init__
    from .libsecret import (  # This uncertain import is deferred till runtime
        LibSecretAgent, trial_run)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/libsecret.py", line 20, in <module>
        raise ImportError("""Unable to import module 'gi'
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    """)  # Message via exception rather than log
    ^^^^
ImportError: Unable to import module 'gi'
Runtime dependency of PyGObject is missing.
Depends on your Linux distro, you could install it system-wide by something like:
    sudo apt install python3-gi python3-gi-cairo gir1.2-secret-1
If necessary, please refer to PyGObject's doc:
https://pygobject.readthedocs.io/en/latest/getting_started.html

Get the project results#

This code gets the project results from the ConceptEV API.

def get_project_results(client, design_instance_id):
    """Get the project results from ConceptEV API.

    Assumes the first results only.
    """
    token = app.get_token(client)
    client.params = {"design_instance_id": design_instance_id}
    concept = app.get(client, "/concepts", id=design_instance_id)

    job_id = concept["jobs_ids"][0]  # get ONLY the first id from each project.
    job_info = app.get_job_info(token, job_id)
    results = app.read_results(
        client, job_info, calculate_units=short_results, filtered=short_results
    )
    # Need to get, Project Name, Component Name, Cost
    arch_id = concept["architecture_id"]
    architecture = app.get(client, f"/architectures/{arch_id}")
    project_results = {
        "architecture": architecture,
        "cost": architecture["components_cost"],
        "design_instance_id": design_instance_id,
        "component_map": app.get_component_id_map(client, design_instance_id),
        "design_name": app.get_design_title(token, design_instance_id),
        "results": results,
    }
    return project_results

Get the project results from a list of design_instance_ids#

This code gets the project results from a list of design instance ids.

def get_results(design_instance_ids):
    """Get results from a list of design instance ids."""

    with app.get_http_client() as client:
        client.timeout = 2000
        project_results = [
            get_project_results(client, design_instance_id)
            for design_instance_id in design_instance_ids
        ]
    return project_results

Get component name from project results.#

This code gets the component name from the project results.

def get_component_name(project_result, name):
    """Get Component Name or returns empty string."""
    name = project_result["component_map"].get(project_result["architecture"][name], "")
    return name

Get results for a drive cycle requirement.#

Get the results for a drive cycle requirement.

def get_drive_cycle_result(project_result, name):
    """Assumes the first requirement in a concept with the matching name is the one we want."""
    requirement = [
        result for result in project_result["results"] if result["requirement"]["name"] == name
    ][0]
    return requirement

Getting all the results.#

First get results of the server or load from file.

if get_results_off_server:
    time.sleep(20)  # Wait for the server to process the results.
    project_results = get_results(design_instance_ids)
    with open("project_results.json", "w") as f:
        json.dump(project_results, f)
else:
    with open("project_results.json", "r") as f:
        project_results = json.load(f)
Encryption unavailable. Opting in to plain text.
Traceback (most recent call last):
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/libsecret.py", line 18, in <module>
    import gi  # https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/Encryption-on-Linux  # pylint: disable=line-too-long
    ^^^^^^^^^
ModuleNotFoundError: No module named 'gi'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/pyconceptev/pyconceptev/src/ansys/conceptev/core/auth.py", line 53, in build_persistence
    return build_encrypted_persistence(location)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/persistence.py", line 98, in build_encrypted_persistence
    return LibsecretPersistence(location)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/persistence.py", line 314, in __init__
    from .libsecret import (  # This uncertain import is deferred till runtime
        LibSecretAgent, trial_run)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/libsecret.py", line 20, in <module>
        raise ImportError("""Unable to import module 'gi'
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    """)  # Message via exception rather than log
    ^^^^
ImportError: Unable to import module 'gi'
Runtime dependency of PyGObject is missing.
Depends on your Linux distro, you could install it system-wide by something like:
    sudo apt install python3-gi python3-gi-cairo gir1.2-secret-1
If necessary, please refer to PyGObject's doc:
https://pygobject.readthedocs.io/en/latest/getting_started.html

Encryption unavailable. Opting in to plain text.
Traceback (most recent call last):
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/libsecret.py", line 18, in <module>
    import gi  # https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/Encryption-on-Linux  # pylint: disable=line-too-long
    ^^^^^^^^^
ModuleNotFoundError: No module named 'gi'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/runner/work/pyconceptev/pyconceptev/src/ansys/conceptev/core/auth.py", line 53, in build_persistence
    return build_encrypted_persistence(location)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/persistence.py", line 98, in build_encrypted_persistence
    return LibsecretPersistence(location)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/persistence.py", line 314, in __init__
    from .libsecret import (  # This uncertain import is deferred till runtime
        LibSecretAgent, trial_run)
  File "/home/runner/work/pyconceptev/pyconceptev/.venv/lib/python3.13/site-packages/msal_extensions/libsecret.py", line 20, in <module>
        raise ImportError("""Unable to import module 'gi'
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    """)  # Message via exception rather than log
    ^^^^
ImportError: Unable to import module 'gi'
Runtime dependency of PyGObject is missing.
Depends on your Linux distro, you could install it system-wide by something like:
    sudo apt install python3-gi python3-gi-cairo gir1.2-secret-1
If necessary, please refer to PyGObject's doc:
https://pygobject.readthedocs.io/en/latest/getting_started.html

Connected to OCM Websockets.
Progress:0.0425531914893617
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.0851063829787234
Status:PHASE_PROGRESS
Progress:0.09787234042553192
Status:PHASE_PROGRESS
Progress:0.11063829787234042
Status:PHASE_PROGRESS
Progress:0.12340425531914893
Status:PHASE_PROGRESS
Progress:0.13617021276595745
Status:PHASE_PROGRESS
Progress:0.14893617021276595
Status:PHASE_PROGRESS
Progress:0.16170212765957448
Status:PHASE_PROGRESS
Progress:0.17446808510638298
Status:PHASE_PROGRESS
Progress:0.18723404255319148
Status:PHASE_PROGRESS
Progress:0.2
Status:PHASE_PROGRESS
Progress:0.2127659574468085
Status:PHASE_PROGRESS
Progress:0.225531914893617
Status:PHASE_PROGRESS
Progress:0.23829787234042554
Status:PHASE_PROGRESS
Progress:0.251063829787234
Status:PHASE_PROGRESS
Progress:0.26382978723404255
Status:PHASE_PROGRESS
Progress:0.2765957446808511
Status:PHASE_PROGRESS
Progress:0.28936170212765955
Status:PHASE_PROGRESS
Progress:0.3021276595744681
Status:PHASE_PROGRESS
Progress:0.3148936170212766
Status:PHASE_PROGRESS
Progress:0.3276595744680851
Status:PHASE_PROGRESS
Progress:0.3404255319148936
Status:PHASE_PROGRESS
Progress:0.35319148936170214
Status:PHASE_PROGRESS
Progress:0.3659574468085106
Status:PHASE_PROGRESS
Progress:0.37872340425531914
Status:PHASE_PROGRESS
Progress:0.39148936170212767
Status:PHASE_PROGRESS
Progress:0.40425531914893614
Status:PHASE_PROGRESS
Progress:0.41702127659574467
Status:PHASE_PROGRESS
Progress:0.4297872340425532
Status:PHASE_PROGRESS
Progress:0.4425531914893617
Status:PHASE_PROGRESS
Progress:0.4553191489361702
Status:PHASE_PROGRESS
Progress:0.46808510638297873
Status:PHASE_PROGRESS
Progress:0.4808510638297872
Status:PHASE_PROGRESS
Progress:0.49361702127659574
Status:PHASE_PROGRESS
Progress:0.5063829787234042
Status:PHASE_PROGRESS
Progress:0.5191489361702127
Status:PHASE_PROGRESS
Progress:0.5319148936170213
Status:PHASE_PROGRESS
Progress:0.5446808510638298
Status:PHASE_PROGRESS
Progress:0.5574468085106383
Status:PHASE_PROGRESS
Progress:0.5702127659574469
Status:PHASE_PROGRESS
Progress:0.5829787234042553
Status:PHASE_PROGRESS
Progress:0.5957446808510638
Status:PHASE_PROGRESS
Progress:0.6085106382978723
Status:PHASE_PROGRESS
Progress:0.6212765957446809
Status:PHASE_PROGRESS
Progress:0.6340425531914894
Status:PHASE_PROGRESS
Progress:0.6468085106382979
Status:PHASE_PROGRESS
Progress:0.6595744680851063
Status:PHASE_PROGRESS
Progress:0.6723404255319149
Status:PHASE_PROGRESS
Progress:0.6851063829787234
Status:PHASE_PROGRESS
Progress:0.6978723404255319
Status:PHASE_PROGRESS
Progress:0.7106382978723405
Status:PHASE_PROGRESS
Progress:0.723404255319149
Status:PHASE_PROGRESS
Progress:0.7361702127659574
Status:PHASE_PROGRESS
Progress:0.7489361702127659
Progress:0.7617021276595745
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.774468085106383
Progress:0.7872340425531915
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.8
Status:PHASE_PROGRESS
Progress:0.8127659574468085
Status:PHASE_PROGRESS
Progress:0.825531914893617
Status:PHASE_PROGRESS
Progress:0.8382978723404255
Status:PHASE_PROGRESS
Progress:0.851063829787234
Status:PHASE_PROGRESS
Progress:0.8638297872340426
Status:PHASE_PROGRESS
Progress:0.8765957446808511
Status:PHASE_PROGRESS
Progress:0.8893617021276595
Status:PHASE_PROGRESS
Progress:0.902127659574468
Status:PHASE_PROGRESS
Progress:0.9148936170212766
Status:PHASE_PROGRESS
Progress:0.9276595744680851
Status:PHASE_PROGRESS
Progress:0.9404255319148936
Status:PHASE_PROGRESS
Progress:0.9531914893617022
Status:PHASE_PROGRESS
Progress:0.9659574468085106
Status:PHASE_PROGRESS
Progress:0.9787234042553191
Status:PHASE_PROGRESS
Progress:0.9914893617021276
Status:PHASE_DONE
Status:uploading
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Status:PHASE_DONE
Status:FINISHED

Output the results to Excel File.#

Create an output results list to store outputs. Loop through all results. Get the data we want to output. Place in a records list for each row of Excel file.

output_results = []
for (
    project_result
) in project_results:  # For each project results get the data we want to output into the row.

    # Parse the results we are interested in.
    steady_drive = get_drive_cycle_result(project_result, "180 km/h")

    # Get the Component Names for each of components we are interested in.
    front_tranmsission_name = (
        get_component_name(project_result, "front_transmission_id") + " (Front)"
    )
    front_motor_name = get_component_name(project_result, "front_motor_id") + " (Front)"
    front_inverter_name = get_component_name(project_result, "front_inverter_id") + " (Front)"
    front_disconnect_clutch_name = (
        get_component_name(project_result, "front_clutch_id") + " (Front)"
    )
    rear_transmission_name = get_component_name(project_result, "rear_transmission_id") + " (Rear)"
    rear_motor_name = get_component_name(project_result, "rear_motor_id") + " (Rear)"
    rear_inverter_name = get_component_name(project_result, "rear_inverter_id") + " (Rear)"
    rear_disconnect_clutch_name = get_component_name(project_result, "rear_clutch_id") + " (Rear)"
    battery_name = get_component_name(project_result, "battery_id")

    # Creating a records list for each row.
    output_results.append(
        {
            "Project Name": project_result["design_name"],
            "Design Instance Id": project_result["design_instance_id"],
            "Front Transmission": front_tranmsission_name,
            "Front Motor": front_motor_name,
            "Front Inverter": front_inverter_name,
            "Rear Transmission": rear_inverter_name,
            "Rear Motor": rear_motor_name,
            "Rear Inverter": rear_inverter_name,
            "Battery": battery_name,
            "Cost": project_result["cost"],
            "total_tractive_power": steady_drive["requirement"]["total_tractive_power"],
            # Extend as required to add the data you need.
        }
    )

Output the results to Excel File.#

Convert the output results to a pandas DataFrame. Output the results to an Excel file.

all_results = pd.DataFrame(output_results)  # Convert to Pandas DataFrame
plt.plot(all_results["Cost"], all_results["total_tractive_power"], "*")  # Plot the results.
plt.show()

all_results.to_excel(output_filename)  # Output to excel.
02 get results workflow

Total running time of the script: (5 minutes 38.396 seconds)

Gallery generated by Sphinx-Gallery