Source code for hed.schema.schema_attribute_validator_hed_id

from hed.schema.schema_io.ontology_util import get_library_data
from hed.schema.schema_io.df_util import remove_prefix
from semantic_version import Version
from hed.schema.hed_schema_io import load_schema_version
from hed.schema.hed_cache import get_hed_versions
from hed.schema.hed_schema_constants import HedKey
from hed.errors.error_types import SchemaAttributeErrors
from hed.errors.error_reporter import ErrorHandler


[docs]class HedIDValidator: """Support class to validate hedIds in schemas"""
[docs] def __init__(self, hed_schema): """Support class to validate hedIds in schemas Parameters: hed_schema(HedSchemaBase): The schema we're validating. It uses this to derive the version number(s) of the previous schema. """ self.hed_schema = hed_schema self._previous_schemas = {} versions = self.hed_schema.version_number.split(",") libraries = self.hed_schema.library.split(",") prev_versions = {} self.library_data = {} for version, library in zip(versions, libraries): prev_version = self._get_previous_version(version, library) if prev_version: prev_versions[library] = prev_version library_data = get_library_data(library) if library_data: self.library_data[library] = library_data # Add the standard schema if we have a with_standard if "" not in prev_versions and self.hed_schema.with_standard: prev_version = self._get_previous_version(self.hed_schema.with_standard, "") if prev_version: prev_versions[""] = prev_version library_data = get_library_data("") if library_data: self.library_data[""] = get_library_data("") if prev_versions: self._previous_schemas = {library: load_schema_version(full_version) for library, full_version in prev_versions.items()}
@staticmethod def _get_previous_version(version, library): current_version = Version(version) all_schema_versions = get_hed_versions(library_name=library) for old_version in all_schema_versions: if Version(old_version) < current_version: prev_version = old_version if library: prev_version = f"{library}_{prev_version}" return prev_version
[docs] def verify_tag_id(self, hed_schema, tag_entry, attribute_name): """Validates the hedID attribute values This follows the template from schema_attribute_validators.py Parameters: hed_schema (HedSchema): The schema to use for validation tag_entry (HedSchemaEntry): The schema entry for this tag. attribute_name (str): The name of this attribute Returns: issues(list): A list of issues from validating this attribute. """ # todo: If you have a way to know the schema should have 100% ids, you could check for that and flag missing new_id = tag_entry.attributes.get(attribute_name, "") old_id = None tag_library = tag_entry.has_attribute(HedKey.InLibrary, return_value=True) if not tag_library: tag_library = "" previous_schema = self._previous_schemas.get(tag_library) if previous_schema: old_entry = previous_schema.get_tag_entry(tag_entry.name, key_class=tag_entry.section_key) if old_entry: old_id = old_entry.attributes.get(HedKey.HedID) if old_id: try: old_id = int(remove_prefix(old_id, "HED_")) except ValueError: # Just silently ignore invalid old_id values(this shouldn't happen) pass if new_id: try: new_id = int(remove_prefix(new_id, "HED_")) except ValueError: return ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_HED_ID_INVALID, tag_entry.name, new_id) # Nothing to verify if new_id is None and old_id is None: return [] issues = [] if old_id and old_id != new_id: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_HED_ID_INVALID, tag_entry.name, new_id, old_id=old_id) library_data = self.library_data.get(tag_library) if library_data and new_id is not None: starting_id, ending_id = library_data["id_range"] if new_id < starting_id or new_id > ending_id: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_HED_ID_INVALID, tag_entry.name, new_id, valid_min=starting_id, valid_max=ending_id) return issues