Generate measurements

For this tutorial you will generate some sample (fake) measurement data so you can post it to your project.

You're going to create a new folder and populate it with JSON files containing the fake measurement data for the whole wafer.

import json
import shutil
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

np.random.seed(42)
df = pd.read_csv("design_manifest.csv")
df
def iv_resistance(resistance, current) -> np.ndarray:
    """Returns IV.

    Args:
        resistance: in Ohms.
        current: electrical intensity in A.

    """
    v = resistance * current
    return v


i = np.linspace(0, 100, 21)
v = iv_resistance(resistance=30, current=i)

plt.plot(i, v)
plt.title("Resistance")
plt.xlabel("Current (A)")
plt.ylabel("V")
plt.grid(True)
plt.show()

Generate wafer definitions

You can define different wafer maps for each wafer.

wafer_map

wafer_definitions = Path("wafer_definitions.json")
wafers = ["2eq221eqewq2", "334abd342zuq", "6d4c615ff105"]
dies = [{"x": x, "y": y} for y in range(-2, 3) for x in range(-2, 3) if not (abs(y) == 2 and abs(x) == 2)]

# Wrap in a list with the wafer information
data = [{"wafer": wafer_pkey, "dies": dies} for wafer_pkey in wafers]

with open(wafer_definitions, "w") as f:
    json.dump(data, f, indent=2)

Generate and write data

You can easily generate some data and add some noise to make it look like a real measurement.

wafers_path = Path("wafers").resolve()
shutil.rmtree(wafers_path, ignore_errors=True)
wafers_path.mkdir(parents=True, exist_ok=True)

metadata = {"measurement_type": "Spectral MEAS", "temperature": 25}

length = 20
ohms_per_square = 100

resistances = []
for wafer in wafers:
    wafer_per_cent_variation = 0.20  # 20% variation
    wafer_variation_factor = 1 + wafer_per_cent_variation * (2 * np.random.rand() - 1)

    for die in dies:
        die = f"{(die['x'])}_{(die['y'])}"
        for (_, row), (_, device_row) in zip(df.iterrows(), df.iterrows(), strict=False):
            cell_id = row["cell"]
            basic_resistance = ohms_per_square * row["width_um"] * length * 1e-12
            device_per_cent_variation = 0.05  # 5% variation
            device_variation_factor = 1 + device_per_cent_variation * (2 * np.random.rand() - 1)
            resistance = basic_resistance * wafer_variation_factor * device_variation_factor

            # Special resistance cases (open and short circuits)
            rand_num = np.random.rand()
            if rand_num < 0.05:
                resistance = 3000  # 5% with infinite resistance (open circuit)
            elif rand_num < 0.08:  # Additional 3% (total 8% chance)
                resistance = 0  # 3% with zero resistance (short circuit)

            top_cell_id = "resistance"
            device_id = f"{top_cell_id}_{cell_id}_{device_row['x']}_{device_row['y']}"
            resistances.append(resistance)
            v = iv_resistance(resistance=resistance, current=i)
            noise = 5e-2 * np.random.rand(len(v)) * v  # add 5% noise
            v += noise
            dirpath = wafers_path / wafer / die / device_id
            dirpath.mkdir(exist_ok=True, parents=True)
            data_file = dirpath / "data.parquet"
            metadata_file = dirpath / "attributes.json"
            metadata_file.write_text(json.dumps(metadata))

            d = {
                "v": v,
                "i": i,
                "polyfit": resistance,
            }
            data = pd.DataFrame(d)
            data.attrs.update(metadata)
            data.to_parquet(data_file)
resistances = np.array(resistances)
plt.title("resistance distribution")
plt.plot(resistances[resistances < 1000], ".")
plt.xlabel("measurement index")
plt.ylabel("resistance")
plt.grid(True)
plt.show()
df = pd.read_parquet("./wafers/2eq221eqewq2/-2_-1/resistance_resistance_sheet_W20_0_157500/data.parquet")
plt.plot(df.i.values, df.v.values)
a, b = np.polyfit(df.i.values, df.v.values, deg=1)
i_arr = np.linspace(df.i.values.min(), df.i.values.max())
plt.plot(i_arr, a * i_arr + b)
plt.grid(True)
plt.show()
df.attrs
On This Page