def cal_f1_all(preds, answers):
    """
    Calculate global F1 accuracy score (field-level, micro-averaged) by counting all true positives,
    false negatives and false positives
    """
    metric_info, error_info = {}, {}
    total_tp, total_fn_or_fp = 0, 0
    for file_name, answer in answers.items():
        sample_error_info = {"fp": [], "fn": [], "tp": []}
        pred = preds.get(file_name, {})
        pred, answer = flatten(normalize_dict(pred)), flatten(normalize_dict(answer))
        for field in pred:
            field_name = field[0]
            if field_name not in metric_info:
                metric_info[field_name] = {"total_tp": 0, "total_fn_or_fp": 0}
            if field in answer:
                total_tp += 1
                metric_info[field_name]["total_tp"] += 1
                sample_error_info["tp"].append(field)
                answer.remove(field)
            else:
                total_fn_or_fp += 1
                metric_info[field_name]["total_fn_or_fp"] += 1
                sample_error_info["fp"].append(field)

        total_fn_or_fp += len(answer)
        for field in answer:
            field_name = field[0]
            if field_name not in metric_info:
                metric_info[field_name] = {"total_tp": 0, "total_fn_or_fp": 0}
            metric_info[field_name]["total_fn_or_fp"] += 1
            sample_error_info["fn"].append(field)

        sample_error_num = sum([len(v) for k, v in sample_error_info.items() if k != "tp"])
        if sample_error_num > 0:
            sample_error_info["error_num"] = sample_error_num
            error_class_list = ["counter_" + x[0] for x in (sample_error_info["fn"] + sample_error_info["fp"])]
            counter = Counter(error_class_list)
            sample_error_info["error_info"] = dict(counter)
            error_info[file_name] = sample_error_info

    # summary
    for field_name, field_info in metric_info.items():
        field_tp, field_fn_or_fp = field_info["total_tp"], field_info["total_fn_or_fp"]
        metric_info[field_name]["acc"] = field_tp / (field_tp + field_fn_or_fp / 2 + 1e-6)

    print("donut_evaluator: total_tp: {}, total_fn_or_fp: {}, ptd_num: {}, gt_num: {}".format(total_tp, total_fn_or_fp,
                                                                                              len(preds), len(answers)))
    error_info = {k: v for k, v in
                  sorted(error_info.items(), key=lambda item: item[1].get("error_num", 0), reverse=True)}
    metric_info = {k: v for k, v in
                   sorted(metric_info.items(), key=lambda item: item[1].get("total_fn_or_fp", 0), reverse=True)}
    return total_tp / (total_tp + total_fn_or_fp / 2 + 1e-6), metric_info, error_info

    Calculate global F1 accuracy score (field-level, micro-averaged) by counting all true positives,
    false negatives and false positives
    
vlmeval/dataset/utils/ccocr_evaluator/kie_evaluator.py