Skip to content

SharePoint Check Upload

BRUCE LIM edited this page Oct 29, 2023 · 1 revision

tMap file Checking

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 ng

CoC file Checking

def 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

Clone this wiki locally