Compare Campaign Measurements

Define measurement query and which measurement quantities to plot

Available Measurement Quantities

Ambient, Coolant, I_d, I_q, Motor_speed, Pm, Stator_tooth, Stator_winding, Stator_yoke, Time, Torque, U_d, U_q

[2]:
mea_result_conditions = {
                "Name": {"$like": "Profile_*"},
                "TestStep.Test.Name": {"$in": ["Campaign_03", "Campaign_04"]},
                "TestStep.Test.StructureLevel.Project.Name": {"$eq": "ElectricMotorTemperature"}
            }

mq_names = ["Motor_speed", "Torque"]

Retrieve content from ASAM ODS ODS service

[3]:
from odsbox import ConI

with ConI(url="https://docker.peak-solution.de:10032/api", auth=("Demo", "mdm")) as con_i:
    # Query measurements to compare
    measurements = con_i.query_data({
            "MeaResult": mea_result_conditions,
            "$attributes": {
                "Name": 1,
                "Id": 1,
                "TestStep": {
                    "Name": 1,
                    "Test": {
                        "Name": 1,
                        "StructureLevel": {
                            "Name": 1,
                            "Project": {
                                "Name": 1
                                }}}},
            },
        })
    measurement_ids = measurements["MeaResult.Id"].tolist()

    # Query submatrices of measurements containing the specified measurement quantities
    submatrices = con_i.query({
            "AoSubMatrix": {
                "measurement": {"$in": measurement_ids},
                "local_columns": {
                    "name": {
                        "$in": mq_names
                    },
                }
            },
            "$attributes": {
                "id": 1,
                "number_of_rows": 1,
                "measurement": 1,
            },
            "$groupby": {
                "id": 1,
                "measurement": 1,
                "number_of_rows": 1,
            }
        })
    submatrix_ids = submatrices["id"].tolist()
    # Get units and other info of local columns in submatrices
    local_columns = con_i.query(
        {
            "AoLocalColumn": {
                "submatrix": {"$in": submatrix_ids},
                "$or": [
                    {"name": {"$in": mq_names}},
                    {"independent": 1}
                ]
            },
            "$attributes": {
                "id": 1,
                "name": 1,
                "independent": 1,
                "measurement_quantity.unit:OUTER.name": 1,
            }
        })
    local_column_ids = local_columns["id"].tolist()
    # Fetch bulk data for local columns
    local_columns_signals = con_i.bulk.query({"id":{"$in": local_column_ids}})

Prepare collected data for plotting

[4]:
import pandas as pd

# lookup for units of local columns
local_column_unit_lookup = dict({row["id"]: row["measurement_quantity.unit:OUTER.name"]
                                 for _, row in local_columns.iterrows()})

# generate title for each submatrix
submatrix_title_lookup = {}
for submatrix_id in submatrix_ids:
    measurement_id = submatrices[submatrices['id'] == submatrix_id]['measurement'].values[0]
    measurement_info = measurements[measurements['MeaResult.Id'] == measurement_id]
    if not measurement_info.empty:
        project = measurement_info['Project.Name'].values[0]
        profile = measurement_info['MeaResult.Name'].values[0]
        campaign = measurement_info['Test.Name'].values[0]
        submatrix_title_lookup[submatrix_id] = f"{project} - {campaign} - {profile}"
    else:
        submatrix_title_lookup[submatrix_id] = f"Submatrix {submatrix_id}"

# Create dataframes for each measurement to compare
measurement_data_items = []
for submatrix_id, df in local_columns_signals.groupby("submatrix"):
    # Create dataframe using name as column names and values as column data
    data_dict = {row['name']: row['values'] for _, row in df.iterrows()}
    sub_df = pd.DataFrame(data_dict)
    if not all(col in sub_df.columns for col in mq_names):
        print(f"Skipping submatrix {submatrix_id} as it lacks required columns.")
        continue

    independent_rows = df[df['independent'] == 1]
    independent_name = "Index"
    independent_unit = "-"
    # Set the independent column as the index
    if not independent_rows.empty:
        independent_name = independent_rows['name'].iloc[0]
        sub_df.set_index(independent_name, inplace=True)
        independent_unit = local_column_unit_lookup.get(independent_rows['id'].iloc[0], '-')
    # create axis labels from name and unit
    label_dict = {name: f"{name} [{local_column_unit_lookup.get(id, '-')}]"
                  for name, id in zip(df['name'], df['id'])}
    # information to be plotted
    measurement_data_items.append({
        "title": f"{submatrix_title_lookup.get(submatrix_id, 'Unknown')} \n(Color: {independent_name} [{independent_unit}])",
        "data": sub_df,
        "labels": label_dict })

# Sort measurement_data_items by title (moved outside the loop)
measurement_data_items.sort(key=lambda x: x["title"])

Plot measurements

[5]:
import matplotlib.pyplot as plt

# Number of submatrices
num_of_plots = len(measurement_data_items)

# Calculate number of rows (3 submatrices per row)
cols = 3
rows = (num_of_plots + cols - 1) // cols  # Ceiling division

fig, axes = plt.subplots(rows, cols, figsize=(15, 5 * rows))
axes = axes.flatten()  # Flatten to 1D array for easy indexing

for i, measurement_data in enumerate(measurement_data_items):
    ax = axes[i]
    measurement_data["data"].plot.scatter(
        x=mq_names[0],
        y=mq_names[1],
        c=measurement_data["data"].index,
        colormap="viridis",
        ax=ax,
        alpha=0.7,
        s=20
    )
    ax.set_xlabel(measurement_data["labels"].get(mq_names[0], mq_names[0]))
    ax.set_ylabel(measurement_data["labels"].get(mq_names[1], mq_names[1]))
    ax.set_title(measurement_data["title"])

# Hide any unused subplots
for j in range(i + 1, len(axes)):
    axes[j].axis('off')

plt.tight_layout()
plt.show()
_images/compare_measurement_8_0.png