Module vcd.sanity

Module to handle verify content in VCD data.

This module implements functions to analyze content coherence.

Expand source code
"""
Module to handle verify content in VCD data.

This module implements functions to analyze content coherence.
"""
# VCD (Video Content Description) library.
#
# Project website: http://vcd.vicomtech.org
#
# Copyright (C) 2023, Vicomtech (http://www.vicomtech.es/),
# (Spain) all rights reserved.
#
# VCD is a Python library to create and manage OpenLABEL content.
# VCD is distributed under MIT License. See LICENSE.

from vcd import core, utils

# NOTE: This module is under development. It does not exhaustively analyze the content
# for coherency.


def check_frame_intervals(vcd: core.VCD) -> bool:
    # This function analyzes a given vcd content and evaluates its internal coherence
    if not isinstance(vcd, core.VCD):
        raise TypeError("Argument 'vcd' must be of type 'vcd.core.VCD'")

    fis_vcd = vcd.get_frame_intervals().get_dict()

    objects = vcd.get_all(core.ElementType.object)
    actions = vcd.get_all(core.ElementType.action)
    events = vcd.get_all(core.ElementType.event)
    contexts = vcd.get_all(core.ElementType.context)
    relations = vcd.get_all(core.ElementType.relation)

    fis_objects = []
    fis_actions = []
    fis_events = []
    fis_contexts = []
    fis_relations = []
    if objects is not None:
        for obj in objects.values():
            fis_objects += obj.get("frame_intervals")
    if actions is not None:
        for action in actions.values():
            fis_actions += action.get("frame_intervals")
    if events is not None:
        for event in events.values():
            fis_events += event.get("frame_intervals")
    if contexts is not None:
        for context in contexts.values():
            fis_contexts += context.get("frame_intervals")
    if relations is not None:
        for relation in relations.values():
            fis_relations += relation.get("frame_intervals")

    fis_elements = utils.fuse_frame_intervals(
        fis_objects + fis_actions + fis_events + fis_contexts + fis_relations
    )

    valid = True
    if not len(fis_vcd) == len(fis_elements):
        valid = False
    else:
        equals = list(map(lambda t1, t2: t1 == t2, fis_vcd, fis_elements))
        if False in equals:
            valid = False

    return valid


def check_frames_elements(vcd: core.VCD) -> bool:
    # This function analyzes a given vcd content and evaluates its internal coherence
    if not isinstance(vcd, core.VCD):
        raise TypeError("Argument 'vcd' must be of type 'vcd.core.VCD'")

    objects = vcd.get_all(core.ElementType.object)
    actions = vcd.get_all(core.ElementType.action)
    events = vcd.get_all(core.ElementType.event)
    contexts = vcd.get_all(core.ElementType.context)
    relations = vcd.get_all(core.ElementType.relation)

    elements_array = [objects, actions, events, contexts, relations]
    names = ["objects", "actions", "events", "contexts", "relations"]

    for counter, elements in enumerate(elements_array):
        if elements is not None:
            for element_key, element_value in elements.items():
                fis_elements_dicts = element_value.get("frame_intervals")
                for fis_element_dict in fis_elements_dicts:
                    frame_start = fis_element_dict["frame_start"]
                    frame_end = fis_element_dict["frame_end"]

                    for frame_num in range(frame_start, frame_end):
                        # Check if this frame_num has an entry with the element
                        frame = vcd.get_frame(frame_num)
                        if frame is None:
                            return False

                        if element_key not in frame[names[counter]]:
                            return False

    return True

Functions

def check_frame_intervals(vcd: VCD) ‑> bool
Expand source code
def check_frame_intervals(vcd: core.VCD) -> bool:
    # This function analyzes a given vcd content and evaluates its internal coherence
    if not isinstance(vcd, core.VCD):
        raise TypeError("Argument 'vcd' must be of type 'vcd.core.VCD'")

    fis_vcd = vcd.get_frame_intervals().get_dict()

    objects = vcd.get_all(core.ElementType.object)
    actions = vcd.get_all(core.ElementType.action)
    events = vcd.get_all(core.ElementType.event)
    contexts = vcd.get_all(core.ElementType.context)
    relations = vcd.get_all(core.ElementType.relation)

    fis_objects = []
    fis_actions = []
    fis_events = []
    fis_contexts = []
    fis_relations = []
    if objects is not None:
        for obj in objects.values():
            fis_objects += obj.get("frame_intervals")
    if actions is not None:
        for action in actions.values():
            fis_actions += action.get("frame_intervals")
    if events is not None:
        for event in events.values():
            fis_events += event.get("frame_intervals")
    if contexts is not None:
        for context in contexts.values():
            fis_contexts += context.get("frame_intervals")
    if relations is not None:
        for relation in relations.values():
            fis_relations += relation.get("frame_intervals")

    fis_elements = utils.fuse_frame_intervals(
        fis_objects + fis_actions + fis_events + fis_contexts + fis_relations
    )

    valid = True
    if not len(fis_vcd) == len(fis_elements):
        valid = False
    else:
        equals = list(map(lambda t1, t2: t1 == t2, fis_vcd, fis_elements))
        if False in equals:
            valid = False

    return valid
def check_frames_elements(vcd: VCD) ‑> bool
Expand source code
def check_frames_elements(vcd: core.VCD) -> bool:
    # This function analyzes a given vcd content and evaluates its internal coherence
    if not isinstance(vcd, core.VCD):
        raise TypeError("Argument 'vcd' must be of type 'vcd.core.VCD'")

    objects = vcd.get_all(core.ElementType.object)
    actions = vcd.get_all(core.ElementType.action)
    events = vcd.get_all(core.ElementType.event)
    contexts = vcd.get_all(core.ElementType.context)
    relations = vcd.get_all(core.ElementType.relation)

    elements_array = [objects, actions, events, contexts, relations]
    names = ["objects", "actions", "events", "contexts", "relations"]

    for counter, elements in enumerate(elements_array):
        if elements is not None:
            for element_key, element_value in elements.items():
                fis_elements_dicts = element_value.get("frame_intervals")
                for fis_element_dict in fis_elements_dicts:
                    frame_start = fis_element_dict["frame_start"]
                    frame_end = fis_element_dict["frame_end"]

                    for frame_num in range(frame_start, frame_end):
                        # Check if this frame_num has an entry with the element
                        frame = vcd.get_frame(frame_num)
                        if frame is None:
                            return False

                        if element_key not in frame[names[counter]]:
                            return False

    return True