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