Untitled
unknown
plain_text
a year ago
17 kB
22
Indexable
import pandas as pd
import re
import numpy as np
# Existing parse_data function
def parse_data(data):
blocks = data.split("{@BLOCK") # Split only at {@BLOCK
global part_number # Declare it globally at the start of the function
measurements = []
platform = "NAN" # Default to NAN if no platform is found
part_number = "" # Default to NAN if no part number is found
skipped_count = 0 # Track number of skipped lines
for block in blocks:
# Ensure the block begins with {@BLOCK
block = "{@BLOCK" + block if not block.startswith("{@BLOCK") else block
# Parse the platform if `@BATCH` and `{@BTEST` are found
if "@BATCH" in block and "{@BTEST" in block:
batch_line = re.search(r"\{@BATCH[^\{]*\{@BTEST[^\{]*", block)
if batch_line:
parts = batch_line.group().split('|')
# Parse platform (9th split logic)
if len(parts) >= 15:
platform = parts[9].strip() # 9th split is index 8 (0-based indexing)
# Parse part number (from index 1 or fallback logic)
if len(parts) > 1 and parts[1].strip():
part_number = parts[1].strip()
else:
for i in range(10, len(parts)): # Start from the 10th part
part = parts[i].strip()
if part:
part_number = part.split("{@BATCH")[0].strip() if "{@BATCH" in part else part.strip()
break
# Define the pattern to match measurement data
pattern = r"\{@([\w-]+)\|([^\|]*)\|([^\|]*)\|?([^\|{]*)\{@(LIM2|LIM3)\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)(?:\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?))?(?:\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?))"
matches = re.findall(pattern, block)
a = []
# Process each match
for match in matches:
prefix = match[0]
if prefix not in {"BLOCK", "BTEST", "BATCH"}: # Ignore these prefixes
a.append(prefix)
# Process `@BTEST` if present
if "{@BTEST" in block:
dataBlockSplit = str(block).split('@BTEST')[1].split("{")[0].split("|")
runs = dataBlockSplit[-1].strip()
serial = dataBlockSplit[1].strip()
datatime = dataBlockSplit[3].strip() if len(dataBlockSplit) > 3 else ""
# Extract test details from `@BLOCK`
block_matches = re.findall(r"@BLOCK\|([^|]+)\|(\d{2})", block)
for test_name, pass_fail_code in block_matches:
# Clean test name
test_name = re.sub(r'^\d+%', '', test_name)
pass_fail = "Pass" if pass_fail_code == "00" else "Fail"
category_matches = re.findall(
r"@([A-Z-]+)\|(\d)\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)(?:\|(.+?))?\{", block
)
# Extract limits
lim2_match = re.findall(
r"@LIM2\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)", block
)
lim3_match = re.findall(
r"@LIM3\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)\|([+-]?\d*\.?\d+(?:E[+-]?\d+)?)",
block
)
if lim3_match:
for num in range(len(lim3_match)):
category_match = category_matches[num]
typeValue = a[num]
subtest = category_match[3] if category_match[3] else "None"
pass_fail_code = category_match[1] # Extract pass/fail code (0 or 1)
measurement = float(category_match[2]) # Extract measurement
pass_fail = "Pass" if pass_fail_code == "0" else "Fail"
upper_limit = lower_limit = nominal_value = np.nan
nominal_value, upper_limit, lower_limit = map(float, lim3_match[num])
# Assuming nominal_value, upper_limit, and lower_limit are defined
tol_plus = (upper_limit - nominal_value) / nominal_value * 100 if not np.isnan(
nominal_value) else np.nan
tol_minus = (lower_limit - nominal_value) / nominal_value * 100 if not np.isnan(
nominal_value) else np.nan
# Format tol_plus and tol_minus to 1 decimal place
tol_plus = round(tol_plus, 1) if not np.isnan(tol_plus) else np.nan
tol_minus = round(tol_minus, 1) if not np.isnan(tol_minus) else np.nan
# Skip logic: Skip if typeValue is "A-JUM" and measurement is negative
if typeValue == "A-JUM" and measurement < 0:
skipped_count += 1 # Increment the skip counter
continue # Skip this iteration
# Ensure tol_minus is positive (absolute value)
tol_minus = abs(tol_minus)
measurements.append({
"Test Name": test_name,
"DateTime": datatime,
"Subtest": subtest,
"Serial#": serial,
"Measure": measurement,
})
elif lim2_match:
for num in range(len(lim2_match)):
if num < len(category_matches):
category_match = category_matches[num]
# Continue processing
else:
# Handle mismatch, e.g., skip or log an error
print(f"Warning: No matching category for index {num} in block.")
continue # Skip the current iteration
typeValue = a[num]
subtest = category_match[3] if category_match[3] else "None"
pass_fail_code = category_match[1]
measurement = float(category_match[2])
pass_fail = "Pass" if pass_fail_code == "0" else "Fail"
upper_limit = lower_limit = nominal_value = np.nan
upper_limit, lower_limit = map(float, lim2_match[num])
tol_plus = (upper_limit - nominal_value) / nominal_value * 100 if not np.isnan(
nominal_value) else np.nan
tol_minus = (lower_limit - nominal_value) / nominal_value * 100 if not np.isnan(
nominal_value) else np.nan
# Skip logic: Skip if typeValue is "A-JUM" and measurement is negative
if typeValue == "A-JUM" and measurement < 0:
skipped_count += 1 # Increment the skip counter
continue # Skip this iteration
measurements.append({
"Test Name": test_name,
"DateTime": datatime,
"Subtest": subtest,
"Serial#": serial,
"Measure": measurement,
})
return pd.DataFrame(measurements), skipped_count
# Simple input and print example
def input_and_parse_data():
# Take input from the user
data = """
{@BATCH|000540-||903|1||btest|240221155154||I30704CE243BQ75|OP5|RevA|OP5||
{@BTEST|24052C0G0|00|240221224006|000017|0|all||n|n|240221224023||001|default_SN1
{@PF|1%pins|0|0
}
{@TS|0|000|000|000|1%shorts
}
{@BLOCK|1%c2|00
{@A-CAP|0|+9.940980E-06{@LIM3|+1.050000E-05|+1.363950E-05|+7.360500E-06}}
}
{@BLOCK|1%c13|00
{@A-CAP|0|+9.767915E-06{@LIM3|+1.000100E-05|+1.299130E-05|+7.010701E-06}}
}
{@BLOCK|1%c15|00
{@A-CAP|0|+9.722146E-06{@LIM3|+1.010000E-05|+1.311990E-05|+7.080100E-06}}
}
{@BLOCK|1%c17|00
{@A-CAP|0|+1.070258E-07{@LIM3|+1.000000E-07|+1.299000E-07|+7.010000E-08}}
}
{@BLOCK|1%c18|00
{@A-CAP|0|+1.113787E-07{@LIM3|+1.000000E-07|+1.296000E-07|+7.010000E-08}}
}
{@BLOCK|1%c12|00
{@A-CAP|0|+1.556213E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%c19|00
{@A-CAP|0|+1.546055E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%c20|00
{@A-CAP|0|+1.651738E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%c21|00
{@A-CAP|0|+1.568304E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%l2|00
{@A-JUM|0|+2.836620E+00{@LIM2|+1.000000E+01|+0.000000E+00}}
}
{@BLOCK|1%r12|00
{@A-RES|0|+9.946286E+02{@LIM3|+1.000000E+03|+1.100000E+03|+9.000000E+02}}
}
{@BLOCK|1%r14|00
{@A-RES|0|+9.884425E+02{@LIM3|+1.000000E+03|+1.100000E+03|+9.000000E+02}}
}
{@BLOCK|1%r17|00
{@A-RES|0|+9.923311E+02{@LIM3|+1.000000E+03|+1.100000E+03|+9.000000E+02}}
}
{@BLOCK|1%r3|00
{@A-RES|0|+1.210560E+05{@LIM3|+1.210000E+05|+1.282600E+05|+1.137400E+05}}
}
{@BLOCK|1%r4|00
{@A-RES|0|+2.468543E+05{@LIM3|+2.490000E+05|+2.639400E+05|+2.340600E+05}}
}
{@BLOCK|1%r6|00
{@A-RES|0|+2.870011E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r8|00
{@A-RES|0|+3.028053E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r13|00
{@A-RES|0|+3.000838E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r18|00
{@A-RES|0|+2.980830E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r15|00
{@A-JUM|0|+2.331387E+00{@LIM2|+1.000000E+01|+0.000000E+00}}
}
{@BLOCK|1%r16|00
{@A-JUM|0|+2.520171E+00{@LIM2|+1.000000E+01|+0.000000E+00}}
}
{@BLOCK|1%d1|00
{@A-ZEN|0|+7.107842E+00{@LIM3|+7.800000E+00|+8.580000E+00|+6.630000E+00}}
}
{@BLOCK|1%d2|00
{@A-ZEN|0|+7.221235E+00{@LIM3|+7.800000E+00|+8.580000E+00|+6.630000E+00}}
}
{@BLOCK|1%u1_clamp_diode|00
{@A-DIO|0|+6.795377E-01|pin_1_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+6.788366E-01|pin_2_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+7.409673E-01|pin_3_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+6.794062E-01|pin_4_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+7.580992E-01|pin_5_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+3.094703E-01|pin_7_gnd{@LIM2|+9.500000E-01|+1.500000E-01}}
{@A-DIO|0|+3.976275E-01|pin_12_gnd{@LIM2|+9.500000E-01|+2.500000E-01}}
{@A-DIO|0|+6.616171E-01|pin_14_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
}
{@BLOCK|1%u2_clamp_diode|00
{@A-DIO|0|+1.796006E-01|pin_1_gnd{@LIM2|+6.500000E-01|+1.000000E-01}}
{@A-DIO|0|+2.157485E-01|pin_2_gnd{@LIM2|+6.500000E-01|+1.000000E-01}}
{@A-DIO|0|+5.671504E-01|pin_4_gnd{@LIM2|+6.500000E-01|+4.000000E-01}}
{@A-DIO|0|+7.377249E-01|pin_5_gnd{@LIM2|+8.500000E-01|+5.000000E-01}}
}
{@BLOCK|1%u3_clamp_diode|00
{@A-DIO|0|+5.671066E-01|pin_11_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.819601E-01|pin_15_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+6.283609E-01|pin_20_gnd{@LIM2|+9.500000E-01|+3.500000E-01}}
{@A-DIO|0|+5.839756E-01|pin_22_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.835813E-01|pin_23_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.844576E-01|pin_28_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.836689E-01|pin_29_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.847205E-01|pin_33_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.877876E-01|pin_34_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+4.068726E-01|pin_41_gnd{@LIM2|+9.500000E-01|+3.000000E-01}}
{@A-DIO|0|+5.843262E-01|pin_42_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
}
{@BLOCK|1%u4_clamp_diode|00
{@A-DIO|0|+2.263519E-01|pin_8_gnd{@LIM2|+6.500000E-01|+1.000000E-01}}
}
{@BLOCK|1%testjet|00
{@TJET|00|0000|1%u1
}
{@TJET|00|0000|1%u3
}
}
{@BLOCK|1%u2|00
{@A-MEA|0|+1.660344E+00|boost{@LIM2|+2.000000E+00|+1.000000E+00}}
{@A-MEA|0|+2.685606E+00|bypass{@LIM2|+3.150000E+00|+1.200000E+00}}
{@D-T|0|384||0|1%u2
}
}
}}
{@BATCH|000540-||903|1||btest|240221093810||I30704CE243BQ75|OP5|RevA|OP5||
{@BTEST|24052C000|00|240221095434|000020|0|all||n|n|240221095454||001|default_SN1
{@PF|1%pins|0|0
}
{@TS|0|000|000|000|1%shorts
}
{@BLOCK|1%c2|00
{@A-CAP|0|+1.015362E-05{@LIM3|+1.050000E-05|+1.363950E-05|+7.360500E-06}}
}
{@BLOCK|1%c13|00
{@A-CAP|0|+9.518092E-06{@LIM3|+1.000100E-05|+1.299130E-05|+7.010701E-06}}
}
{@BLOCK|1%c15|00
{@A-CAP|0|+9.622979E-06{@LIM3|+1.010000E-05|+1.311990E-05|+7.080100E-06}}
}
{@BLOCK|1%c17|00
{@A-CAP|0|+1.063337E-07{@LIM3|+1.000000E-07|+1.299000E-07|+7.010000E-08}}
}
{@BLOCK|1%c18|00
{@A-CAP|0|+1.096751E-07{@LIM3|+1.000000E-07|+1.296000E-07|+7.010000E-08}}
}
{@BLOCK|1%c12|00
{@A-CAP|0|+1.621750E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%c19|00
{@A-CAP|0|+1.615462E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%c20|00
{@A-CAP|0|+1.640613E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%c21|00
{@A-CAP|0|+1.630214E-09{@LIM3|+1.500000E-09|+1.875000E-09|+1.125000E-09}}
}
{@BLOCK|1%l2|00
{@A-JUM|0|+2.828650E+00{@LIM2|+1.000000E+01|+0.000000E+00}}
}
{@BLOCK|1%r12|00
{@A-RES|0|+9.896323E+02{@LIM3|+1.000000E+03|+1.100000E+03|+9.000000E+02}}
}
{@BLOCK|1%r14|00
{@A-RES|0|+9.917171E+02{@LIM3|+1.000000E+03|+1.100000E+03|+9.000000E+02}}
}
{@BLOCK|1%r17|00
{@A-RES|0|+9.903231E+02{@LIM3|+1.000000E+03|+1.100000E+03|+9.000000E+02}}
}
{@BLOCK|1%r3|00
{@A-RES|0|+1.209783E+05{@LIM3|+1.210000E+05|+1.282600E+05|+1.137400E+05}}
}
{@BLOCK|1%r4|00
{@A-RES|0|+2.471828E+05{@LIM3|+2.490000E+05|+2.639400E+05|+2.340600E+05}}
}
{@BLOCK|1%r6|00
{@A-RES|0|+2.884832E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r8|00
{@A-RES|0|+3.004989E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r13|00
{@A-RES|0|+2.972655E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r18|00
{@A-RES|0|+3.003106E+06{@LIM3|+3.000000E+06|+3.300000E+06|+2.700000E+06}}
}
{@BLOCK|1%r15|00
{@A-JUM|0|+2.359659E+00{@LIM2|+1.000000E+01|+0.000000E+00}}
}
{@BLOCK|1%r16|00
{@A-JUM|0|+2.528427E+00{@LIM2|+1.000000E+01|+0.000000E+00}}
}
{@BLOCK|1%d1|00
{@A-ZEN|0|+7.104972E+00{@LIM3|+7.800000E+00|+8.580000E+00|+6.630000E+00}}
}
{@BLOCK|1%d2|00
{@A-ZEN|0|+7.247071E+00{@LIM3|+7.800000E+00|+8.580000E+00|+6.630000E+00}}
}
{@BLOCK|1%u1_clamp_diode|00
{@A-DIO|0|+6.788804E-01|pin_1_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+6.781356E-01|pin_2_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+7.446916E-01|pin_3_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+6.773469E-01|pin_4_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+7.584059E-01|pin_5_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+3.095579E-01|pin_7_gnd{@LIM2|+9.500000E-01|+1.500000E-01}}
{@A-DIO|0|+3.947794E-01|pin_12_gnd{@LIM2|+9.500000E-01|+2.500000E-01}}
{@A-DIO|0|+6.624057E-01|pin_14_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
}
{@BLOCK|1%u2_clamp_diode|00
{@A-DIO|0|+1.801263E-01|pin_1_gnd{@LIM2|+6.500000E-01|+1.000000E-01}}
{@A-DIO|0|+2.163181E-01|pin_2_gnd{@LIM2|+6.500000E-01|+1.000000E-01}}
{@A-DIO|0|+5.671504E-01|pin_4_gnd{@LIM2|+6.500000E-01|+4.000000E-01}}
{@A-DIO|0|+7.378564E-01|pin_5_gnd{@LIM2|+8.500000E-01|+5.000000E-01}}
}
{@BLOCK|1%u3_clamp_diode|00
{@A-DIO|0|+5.667999E-01|pin_11_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.827926E-01|pin_15_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+6.286238E-01|pin_20_gnd{@LIM2|+9.500000E-01|+3.500000E-01}}
{@A-DIO|0|+5.840195E-01|pin_22_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.832746E-01|pin_23_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.836689E-01|pin_28_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.830555E-01|pin_29_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.837566E-01|pin_33_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+5.873494E-01|pin_34_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
{@A-DIO|0|+4.056457E-01|pin_41_gnd{@LIM2|+9.500000E-01|+3.000000E-01}}
{@A-DIO|0|+5.855968E-01|pin_42_gnd{@LIM2|+9.500000E-01|+4.500000E-01}}
}
{@BLOCK|1%u4_clamp_diode|00
{@A-DIO|0|+2.209188E-01|pin_8_gnd{@LIM2|+6.500000E-01|+1.000000E-01}}
}
{@BLOCK|1%testjet|00
{@TJET|00|0000|1%u1
}
{@TJET|00|0000|1%u3
}
}
{@BLOCK|1%u2|00
{@A-MEA|0|+1.667443E+00|boost{@LIM2|+2.000000E+00|+1.000000E+00}}
{@A-MEA|0|+2.686483E+00|bypass{@LIM2|+3.150000E+00|+1.200000E+00}}
{@D-T|0|384||0|1%u2
}
}
}}
"""
# Parse the data using the existing function
df, skipped = parse_data(data)
# Redirect output to a text file
output_file = "parsed_output.txt"
with open(output_file, "w") as f:
# Write parsed details to the file
f.write("\nParsed Data:\n")
f.write(df.to_string(index=False)) # Ensure readable DataFrame output
f.write(f"\nSkipped Count: {skipped}\n")
print(f"Output written to {output_file}")
# Call the function to input and parse data
input_and_parse_data()
Editor is loading...
Leave a Comment