def execute()

in broadcast-monitoring/src/logo_detect/app/team_logo_check.py [0:0]


    def execute(self, expected_program_info, detected_logos):
        """
        Compare the detected logos against the names of the expected teams
        return the matching detecttions


        :param expected: Expected Program data
        {
            "Team_Info": "AVL V NOR",
            "Station_Logo": "Prime Video",
                ...
            "Start_Time": 180,
            "languageCode": "en-en",
            "Segment_Start_Time_In_Loop": 189.9875
        }
        :param data:
          [
            {
              "Name": "aston_villa",
              "Confidence": 88.0790023803711,
              "Geometry": {
                "BoundingBox": {
                  "Width": 0.03180000185966492,
                  "Height": 0.07208999991416931,
                  "Left": 0.23874999582767487,
                  "Top": 0.2536500096321106
                }
              }
            },
            ...
          ]
        """
        team_info = TeamInfoFactory()
        expected_teams = parse_expected_teams(team_info, expected_program_info.get('Team_Info'))
        expected_teams.sort(key=lambda t: t.team_id)

        if expected_teams is None:
            logger.info('Expected Team Info not found')
            return

        logo_detections = defaultdict(list)
        for detection in detected_logos:
            detected_team = team_info.get_team_from_id(detection['Name'])
            if detected_team is None:
                logger.info(f'found no team matching id: {detection["Name"]}')
                continue
            detection['name'] = detected_team.name
            detection['id'] = detected_team.team_id
            del detection['Name']
            logo_detections[detected_team.team_id].append(detection)
        logger.info(f'team logo detected: {json.dumps(logo_detections, indent=2)}')

        # determine all keys in the detected logos dict that do NOT correspond with the
        # expected teams
        expected_ids = [team.team_id for team in expected_teams]
        non_matching_team_ids = [key for key in logo_detections.keys() if key not in expected_ids]
        non_matching_team_ids.sort()
        logger.info(f'expected: {expected_ids}; found teams not expected: {non_matching_team_ids}')
        non_matching_team_ids = deque(non_matching_team_ids)

        for i, team in enumerate(expected_teams, 1):
            team_logo_detections = logo_detections.get(team.team_id)
            prefix = f'Team{i}_Logo'

            # when no logo detections are found for the expected team, use the remaining detections
            # for the "non" expected teams...these are True Negatives
            if team_logo_detections is None:
                logger.info('No logos detected for team id: %s', team.team_id)
                if non_matching_team_ids:
                    team_logo_detections = logo_detections.get(non_matching_team_ids.popleft())
                    logger.info(f'Found {team_logo_detections} instead')
                else:
                    team_logo_detections = []
            yield f'{prefix}_Expected', {'id': team.team_id, 'name': team.name}
            yield f'{prefix}_Detected', team_logo_detections

            confidence = max([det['Confidence'] for det in team_logo_detections]) if team_logo_detections else 0
            yield f'{prefix}_Confidence', confidence

            # test the team_ids from the expected teams match the keys of the detections
            if team.team_id in logo_detections:
                yield f'{prefix}_Status', True
            elif team_logo_detections:
                # team logos not matching the expected team were detected. This is a hard false
                yield f'{prefix}_Status', False
            else:
                # when no logo status is detected, omit this attr.  This is an implicit None
                logger.info('No Logo status decided for Team%d - %s', i, team.name)