def evaluate(self, 
                 annotation_file: str,
                 prediction_file: str,
                 quantized_size: int = 32,
                 verbose: bool = False,
                ):
        """
        annotation file is the gt json file, we use that to generate input for kosmos
        prediction file is the output from kosmos
        """
        recall_tracker = RecallTracker(self.topk)
        
        gt_json = json.load(open(annotation_file, 'r', encoding='utf-8'))
        with open(prediction_file, 'r', encoding='utf-8') as f:
            predict_all_lines = f.readlines()
        # filter the invaild lines for predict_all_lines
        filter_prediction_lines = []
        for line in predict_all_lines:
            line_pieces = line.strip('\n').split('\t')
            if 'H-' in line_pieces[0]:
                if line_pieces[0].split('-')[-1].isdigit():
                    filter_prediction_lines.append(line)
        
        predict_all_lines = filter_prediction_lines
        predict_index = -1
        
        valid_cnt = 0
        for item in tqdm(gt_json['images']):
            # file_name = item["file_name"]
            caption = item["caption"]
            img_height = float(item['height'])
            img_width = float(item['width'])
            postive_item_pos = item['tokens_positive_eval']
            # to verify 
            phrases_from_self = self.imgid2sentences[str(item['original_img_id'])][int(item['sentence_id'])]
            for pos in postive_item_pos:
                # pdb.set_trace()
                if predict_index == len(predict_all_lines):
                    break
                predict_index += 1
                
                pos_start, pos_end = pos[0]
                phrase = caption[pos_start:pos_end]
                phrase_from_self = [p for p in phrases_from_self if p['phrase'] == phrase]
                if len(phrase_from_self) == 0:
                    raise ValueError(f"Can't find the corresponding gt from two file {phrase} vs. {phrases_from_self}")
                else:
                    phrase_from_self = phrase_from_self[0]
                    
                # get the prediction from text line
                try:
                    prediction_line = predict_all_lines[predict_index]
                except IndexError as e:
                    print("Raise Indexerror.")
                    print(f"prediction index / length: {predict_index} / {len(predict_all_lines)}")
                    import sys
                    sys.exit(0)
                
                collect_entity_location = decode_bbox_from_caption(prediction_line, quantized_size=quantized_size, verbose=verbose)
                
                predict_boxes = []
                for (p_pred, p_x1, p_y1, p_x2, p_y2) in collect_entity_location:
                    if p_pred.strip() != phrase.strip(): # get the matched noun phrase
                        continue
                    else:
                        pred_box = [p_x1 * img_width, p_y1 * img_height, p_x2 * img_width, p_y2 * img_height]
                        predict_boxes.append(pred_box)
                
                if len(predict_boxes) == 0:
                    print(f"Can't find valid bbox for the given phrase ({phrase}) in caption ({caption}), \n{collect_entity_location}")
                    print(f"We set a 0-area box to calculate recall result")
                    predict_boxes = [[0., 0., 0., 0.]]
                
                # evaluate
                target_boxes = self.imgid2boxes[str(item['original_img_id'])][phrase_from_self["phrase_id"]]
                ious = box_iou(np.asarray(predict_boxes), np.asarray(target_boxes))
                for k in self.topk:
                    maxi = 0
                    if k == -1:
                        maxi = ious.max()
                    else:
                        assert k > 0
                        maxi = ious[:k].max()
                    if maxi >= self.iou_thresh:
                        recall_tracker.add_positive(k, "all")
                        for phrase_type in phrase_from_self["phrase_type"]:
                            recall_tracker.add_positive(k, phrase_type)
                    else:
                        recall_tracker.add_negative(k, "all")
                        for phrase_type in phrase_from_self["phrase_type"]:
                            recall_tracker.add_negative(k, phrase_type)
                            
                # pdb.set_trace()
                valid_cnt += 1
        print(f"Valid prediction {valid_cnt}/{len(predict_all_lines)}")     
        self.results = recall_tracker.report()
        return self.results

        annotation file is the gt json file, we use that to generate input for kosmos
        prediction file is the output from kosmos
        
kosmos-2/evaluation/flickr_entities/flickr_entities_evaluate.py