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.
Status:PHASE_PROGRESS
Progress:0.0392156862745098
Status:PHASE_PROGRESS
Progress:0.0784313725490196
Status:PHASE_PROGRESS
Progress:0.11764705882352941
Status:PHASE_PROGRESS
Progress:0.1568627450980392
Status:PHASE_PROGRESS
Progress:0.16862745098039217
Progress:0.1803921568627451
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.19215686274509805
Status:PHASE_PROGRESS
Progress:0.20392156862745098
Status:PHASE_PROGRESS
Progress:0.21568627450980393
Status:PHASE_PROGRESS
Progress:0.22745098039215686
Status:PHASE_PROGRESS
Progress:0.23921568627450981
Status:PHASE_PROGRESS
Progress:0.25098039215686274
Progress:0.2627450980392157
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.27450980392156865
Progress:0.28627450980392155
Status:PHASE_PROGRESS
Progress:0.2980392156862745
Status:PHASE_PROGRESS
Progress:0.30980392156862746
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.3215686274509804
Progress:0.3333333333333333
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.34509803921568627
Status:PHASE_PROGRESS
Progress:0.3568627450980392
Status:PHASE_PROGRESS
Progress:0.3686274509803922
Status:PHASE_PROGRESS
Progress:0.3803921568627451
Status:PHASE_PROGRESS
Progress:0.39215686274509803
Progress:0.403921568627451
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.41568627450980394
Status:PHASE_PROGRESS
Progress:0.42745098039215684
Progress:0.4392156862745098
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.45098039215686275
Status:PHASE_PROGRESS
Progress:0.4627450980392157
Status:PHASE_PROGRESS
Progress:0.4745098039215686
Status:PHASE_PROGRESS
Progress:0.48627450980392156
Status:PHASE_PROGRESS
Progress:0.4980392156862745
Status:PHASE_PROGRESS
Progress:0.5098039215686274
Progress:0.5215686274509804
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.5333333333333333
Progress:0.5450980392156862
Status:PHASE_PROGRESS
Progress:0.5568627450980392
Status:PHASE_PROGRESS
Progress:0.5686274509803921
Status:PHASE_PROGRESS
Progress:0.5803921568627451
Status:PHASE_PROGRESS
Progress:0.592156862745098
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.6039215686274509
Status:PHASE_PROGRESS
Progress:0.615686274509804
Progress:0.6274509803921569
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.6392156862745098
Status:PHASE_PROGRESS
Progress:0.6509803921568628
Progress:0.6627450980392157
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.6745098039215687
Status:PHASE_PROGRESS
Progress:0.6862745098039216
Status:PHASE_PROGRESS
Progress:0.6980392156862745
Status:PHASE_PROGRESS
Progress:0.7098039215686275
Progress:0.7215686274509804
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.7333333333333333
Progress:0.7450980392156863
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.7568627450980392
Status:PHASE_PROGRESS
Progress:0.7686274509803922
Status:PHASE_PROGRESS
Progress:0.7803921568627451
Progress:0.792156862745098
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.803921568627451
Status:PHASE_PROGRESS
Progress:0.8156862745098039
Progress:0.8274509803921568
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.8392156862745098
Status:PHASE_PROGRESS
Progress:0.8509803921568627
Status:PHASE_PROGRESS
Progress:0.8627450980392157
Status:PHASE_PROGRESS
Progress:0.8745098039215686
Status:PHASE_PROGRESS
Progress:0.8862745098039215
Progress:0.8980392156862745
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.9098039215686274
Status:PHASE_PROGRESS
Progress:0.9215686274509803
Status:PHASE_PROGRESS
Progress:0.9333333333333333
Progress:0.9450980392156862
Status:PHASE_PROGRESS
Status:PHASE_PROGRESS
Progress:0.9568627450980393
Status:PHASE_PROGRESS
Progress:0.9686274509803922
Status:PHASE_PROGRESS
Progress:0.9803921568627451
Status:PHASE_PROGRESS
Progress:0.9921568627450981
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 53.173 seconds)

Gallery generated by Sphinx-Gallery