-
Notifications
You must be signed in to change notification settings - Fork 0
SharePoint Check Upload
BRUCE LIM edited this page Oct 29, 2023
·
1 revision
def tMap_check_result(self, file_path, file_name, boxno):
ng_messages = [] # Initialize a list to store "ng" messages
self.log_tMap = []
try:
wafer_id_to_find = file_name.split('_')[0]
index = self.waferIds.index(wafer_id_to_find)
good_die = self.goodDies[index]
# Check 1: DataFrameがデータを正しく解釈し、各列に対して数学的な計算や文字列の操作など、特定の操作が期待どおりに機能すること及び空白なしを確認する
# Define the values to be treated as missing or NaN
na_values = ['NA', 'N/A', 'NaN', 'null', '']
# Define data types for specific columns
specific_column_types = {
'CHIP_NUM': str,
'WAFER_NUM_BOTTOM':str
} # Add more columns and data types as needed
# Get the data types from the get_column_types function
column_types_dict = self.get_column_types(file_path)
# Merge the two dictionaries
combined_column_types = {**column_types_dict, **specific_column_types}
# Read the CSV file with the combined data types
df = pd.read_csv(file_path, dtype=specific_column_types, na_values=na_values)
# Check for empty values in the DataFrame
if df.isna().any().any():
raise Exception("Empty values detected in the CSV file.")
# Iterate through columns and check for mixed data types
for column in df.columns:
mixed_types = df[column].apply(type).nunique() > 1
if mixed_types:
raise Exception(f"Column '{column}' contains mixed data types.")
self.log_tMap.append(f" Check 1 : 各列に異なるデータ型や空の値が混在していないこと - OK")
# Check 2:データの数量が出荷数と一致しているか
# Get and Check the number of rows in the DataFrame with the goo_die qty
total_csv_rows = df.shape[0]
if total_csv_rows!=int(good_die):
ng_messages.append(f"\nRWID_GOOD_DIE ({good_die}) != ({total_csv_rows}) tMapのデータ数と出荷数が一致しない.")
self.log_tMap.append(f" Check 2 : 'RWID_GOOD_DIE' ({good_die}) == ({total_csv_rows}) tMapのデータ数と出荷数 - NG")
else:
self.log_tMap.append(f" Check 2 : 'RWID_GOOD_DIE' ({good_die}) == ({total_csv_rows}) tMapのデータ数と出荷数 - OK")
# Check 3 : WAFER_NUM_BOTTOMの範囲(1-25)
wafer_num_bottom = df['WAFER_NUM_BOTTOM'].astype(int)
if not (wafer_num_bottom.between(1, 25).all()):
ng_messages.append("\n'WAFER_NUM_BOTTOM' 列の値は1から25の範囲内である必要があります.")
self.log_tMap.append(f" Check 3 : 'WAFER_NUM_BOTTOM' 列の値は1から25の範囲内であること - NG")
else:
self.log_tMap.append(f" Check 3 : 'WAFER_NUM_BOTTOM' 列の値は1から25の範囲内であること - OK")
# Check 4 : APP_SERIALのチェック
check4 = 0
check4_ng=[]
for i, data in enumerate(df["APP_SERIAL"], start=1):
plant_code = data[:3]
year_code = data[3]
week_code = data[4:6]
weekday_code = data[6]
serial_code = data[7:11]
engconf_code = data[11:15]
revision_code = data[15]
# Check 4.1 : 'APP_SERIAL'の'PlantCode'に'I'または'O'の文字が存在するか確認する
if 'I' in plant_code or 'O' in plant_code:
ng_messages.append(f"'APP_SERIAL' 行{i}のPlantCodeが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のPlantCodeが変.")
check4 = 1
break # Exit the loop
# Check 4.2 : 'APP_SERIAL'の'Year'数字である必要があります
if not year_code.isdigit():
ng_messages.append(f"'APP_SERIAL' 行{i}のYearが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のYearが変.")
check4 = 1
break # Exit the loop
# Check 4.3 : 'APP_SERIAL'の'Week'数字である必要があります(1から53の範囲内)
if not week_code.isdigit() or not (1 <= int(week_code) <= 53):
ng_messages.append(f"'APP_SERIAL' 行{i}のWeekが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のWeekが変.")
check4 = 1
break # Exit the loop
# Check 4.4 : 'APP_SERIAL'の'Weekday'数字である必要があります(1から7の範囲内)
if not weekday_code.isdigit() or not (1 <= int(weekday_code) <= 7):
ng_messages.append(f"'APP_SERIAL' 行{i}のWeekdayが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のWeekdayが変.")
check4 = 1
break # Exit the loop
# Check 4.5: SerialCodeの'I'または'O'の文字の存在チェック
if 'I' in serial_code or 'O' in serial_code:
ng_messages.append(f"'APP_SERIAL' 行{i}のSerialCodeが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のSerialCodeが変.")
check4 = 1
break # Exit the loop
# Check 4.6: EngConfigが '1P27' であることの確認
if engconf_code != "1P27":
ng_messages.append(f"'APP_SERIAL' 行{i}のEngConfigが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のEngConfigが変.")
check4 = 1
break # Exit the loop
# Check 4.7: RevisionCodeの'I'または'O'の文字の存在チェック
if 'I' in revision_code or 'O' in revision_code:
ng_messages.append(f"'APP_SERIAL' 行{i}のRevisionCodeが変.")
check4_ng.append(f" 'APP_SERIAL' 行{i}のRevisionCodeが変.")
check4 = 1
break # Exit the loop
# Check 4.8: APP_SERIAL内に記号が含まれていないことの確認
if not data[7:].isalnum():
ng_messages.append(f"'APP_SERIAL' 行{i}に記号が含まれている.")
check4_ng.append(f" 'APP_SERIAL' 行{i}に記号が含まれている.")
check4 = 1
break # Exit the loop
if check4 == 0:
self.log_tMap.append(f" Check 4 : 'APP_SERIAL'の内部チェック - OK")
else:
self.log_tMap.append(f" Check 4 : 'APP_SERIAL'の内部チェック - NG")
self.log_tMap.extend(check4_ng)
# Check 5 : "FAB_LOT_ID"のすべての値が対応する"FAB_WF_ID"の値を含むか確認
fab_lot_id_check = df.apply(lambda row: row["FAB_LOT_ID"] == row["FAB_WF_ID"].split('-')[0], axis=1)
if not fab_lot_id_check.all():
ng_messages.append(f"\nすべての 'FAB_LOT_ID' の値が 'FAB_WF_ID' と一致していません.")
self.log_tMap.append(f" Check 5 : 'FAB_LOT_ID' の値が 'FAB_WF_ID' と一致 - NG")
else:
self.log_tMap.append(f" Check 5 : 'FAB_LOT_ID' の値が 'FAB_WF_ID' と一致 - OK")
# Check 6 : "RW_WF_ID"の値がアンダースコアの前の部分と等しいか確認
rw_wf_id_check = df.apply(lambda row: row["RW_WF_ID"] == file_name.split('_')[0], axis=1)
if not rw_wf_id_check.all():
ng_messages.append(f"\nすべての 'RW_WF_ID' の値が '{file_name}' に一致していません.")
self.log_tMap.append(f" Check 6 : すべての 'RW_WF_ID' の値が '{file_name}' に一致 - NG")
else:
self.log_tMap.append(f" Check 6 : すべての 'RW_WF_ID' の値が '{file_name}' に一致 - OK")
# Check 7 : "RW_LOT_ID"の値が常に"RW_WF_ID"より2文字少ないか確認
rw_lot_id_check = df.apply(lambda row: row["RW_WF_ID"].startswith(row["RW_LOT_ID"]) and len(row["RW_WF_ID"]) - len(row["RW_LOT_ID"]) == 2, axis=1)
if not rw_lot_id_check.all():
ng_messages.append(f"\nすべての 'RW_LOT_ID' の値が 'RW_WF_ID' に一致していません.")
self.log_tMap.append(f" Check 7 : すべての 'RW_LOT_ID' の値が 'RW_WF_ID' に一致 - NG")
else:
self.log_tMap.append(f" Check 7 : すべての 'RW_LOT_ID' の値が 'RW_WF_ID' に一致 - OK")
# Check 8 : spec.csvの仕様に基づいて値の範囲をチェックする
df_spec = pd.read_csv(self.tMap_spec_path, index_col='item')
# spec.csv情報取得
check8 = 0
check8_ng = []
for index, row in df_spec.iterrows():
length = row['fixed_length']
min_value = row['min_value']
max_value = row['max_value']
if not np.isnan(length):
check_item = df[index].astype(str)
if not check_item.str.len().eq(length).all():
ng_messages.append(f"'{check_item.name}' 列の値は{int(length)}文字である必要があります.")
check8= 1
check8_ng.append(f" '{check_item.name}' 列の値は{int(length)}文字である必要があります.")
if not (np.isnan(min_value) or np.isnan(max_value)):
check_item = df[index].astype(float)
if not (check_item.between(min_value, max_value).all()):
ng_messages.append(f"'{check_item.name}' 列の値は{min_value}から{max_value}の範囲内である必要があります.")
check8_ng.append(f" '{check_item.name}' 列の値は{min_value}から{max_value}の範囲内である必要があります.")
check8 = 1
if check8 == 0:
self.log_tMap.append(f" Check 8 : spec.csvの仕様に基づいて値の範囲をチェック - OK")
else:
self.log_tMap.append(f" Check 8 : spec.csvの仕様に基づいて値の範囲をチェック - NG")
self.log_tMap.extend(check8_ng)
if ng_messages:
ng = ', '.join(ng_messages) # Combine "ng" messages into a comma-separated string
return ng
return None
except pd.errors.ParserError as e:
ng_messages.append(f"\nパース中にエラーが発生しました: {e}")
except Exception as e:
ng_messages.append(f"\nデータ型が異なる列があります: {e}")
self.log_tMap.append(f"Check 1 : 各列に異なるデータ型や空の値が混在していないこと - NG: {e}")
ng = ', '.join(ng_messages) # Combine all "ng" messages into a comma-separated string
return ngdef CoC_check_result(self, file_path, file_name, boxno):
self.log_CoC = []
ng_messages = [] # Initialize a list to store "ng" messages
wafer_id_to_find = file_name.split('_')[0]
index = self.waferIds.index(wafer_id_to_find)
lotno = self.lotnos[index]
total_die = self.totalDies[index]
good_die = self.goodDies[index]
avi_rev = self.rev[index]
# Read the CSV with dtype specified for each column
df = pd.read_csv(file_path)
checks = {
"CoC列一致": (self.CoC_expected_columns, df[df.columns[0]].tolist(), f"CoCファイル '{file_name}' の列が期待される列と一致しません."),
"RW_LOT_TOTAL_DIE_QTY": (self.LOT_TOTAL_DIE, df[df.columns[4]].tolist()[5], f"RW_LOT_TOTAL_DIE_QTY ({df[df.columns[4]].tolist()[5]}) != ({self.LOT_TOTAL_DIE}) COCと編成情報のLOT_TOTAL_DIE_QTYが一致しない."),
"RW_LOT_GOOD_DIE_QTY": (self.LOT_GOOD_DIE, df[df.columns[4]].tolist()[6], f"RW_LOT_GOOD_DIE_QTY ({df[df.columns[4]].tolist()[6]}) != ({self.LOT_GOOD_DIE}) COCと編成情報のLOT_GOOD_DIE_QTYが一致しない."),
"RW_WF_TOTAL_DIE_QTY": (total_die, df[df.columns[4]].tolist()[17], f"RW_WF_TOTAL_DIE_QTY ({df[df.columns[4]].tolist()[17]}) != ({total_die}) COCと{wafer_id_to_find}編成情報のRWID_TOTAL_DIEが一致しない."),
"RW_WF_GOOD_DIE_QTY": (good_die, df[df.columns[4]].tolist()[18], f"RW_WF_GOOD_DIE_QTY ({df[df.columns[4]].tolist()[18]}) != ({good_die}) COCと{wafer_id_to_find}編成情報のRWID_GOOD_DIEが一致しない."),
"RW_LOT_SHIPPING_DATE": (self.SHIP_DATE, df[df.columns[4]].tolist()[7], f"RW_LOT_SHIPPING_DATE ({df[df.columns[4]].tolist()[7]}) != ({self.SHIP_DATE}) COCと編成情報のSHIP_DATEが一致しない."),
"RW_LOT_COC_FILENAME": (file_name, df[df.columns[4]].tolist()[8], f"RW_LOT_COC_FILENAME ({df[df.columns[4]].tolist()[8]}) != ({file_name}) COCと編成情報のfile_nameが一致しない."),
"RW_LOT_FINAL_AVI_REV#": (avi_rev[-2:], df[df.columns[4]].tolist()[10][-2:], f"RW_LOT_FINAL_AVI_REV ({df[df.columns[4]].tolist()[10][-2:]}) != ({avi_rev[-2:]}) COCと{wafer_id_to_find}編成情報のRW_LOT_FINAL_AVI_REVが一致しない."),
}
for check_name, (expected_value, actual_value, message) in checks.items():
if expected_value != actual_value:
ng_messages.append(f"\n{message}")
self.log_CoC.append(f" {message}")
if ng_messages:
ng = ', '.join(ng_messages) # Combine "ng" messages into a comma-separated string
return ng
return None