Skip to content

Commit

Permalink
Documentation cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
VisLab committed Feb 15, 2024
1 parent cb96692 commit d8f4a94
Show file tree
Hide file tree
Showing 20 changed files with 339 additions and 165 deletions.
1 change: 0 additions & 1 deletion hed/schema/schema_io/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
""" XML, OWL, and MediaWiki IO routines. """
52 changes: 25 additions & 27 deletions hed/schema/schema_io/base2schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@


class SchemaLoader(ABC):
""" Baseclass for schema loading, to handle basic errors and partnered schemas.
""" Baseclass for schema loading, to handle basic errors and partnered schemas
Expected usage is SchemaLoaderXML.load(filename).
Expected usage is SchemaLoaderXML.load(filename)
SchemaLoaderXML(filename) will load just the header_attributes.
SchemaLoaderXML(filename) will load just the header_attributes
"""
def __init__(self, filename, schema_as_string=None, schema=None, file_format=None, name=""):
""" Load the given schema from one of the two parameters.
"""Loads the given schema from one of the two parameters.
Parameters:
filename(str or None): A valid filepath or None.
schema_as_string(str or None): A full schema as text or None.
schema(HedSchema or None): A HED schema to merge this new file into.
filename(str or None): A valid filepath or None
schema_as_string(str or None): A full schema as text or None
schema(HedSchema or None): A hed schema to merge this new file into
It must be a with-standard schema with the same value.
file_format(str or None): The format of this file if needed(only for owl currently)
name(str or None): Optional user supplied identifier, by default uses filename.
name(str or None): Optional user supplied identifier, by default uses filename
"""
if schema_as_string and filename:
raise HedFileError(HedExceptions.BAD_PARAMETERS, "Invalid parameters to schema creation.",
Expand Down Expand Up @@ -61,8 +61,7 @@ def __init__(self, filename, schema_as_string=None, schema=None, file_format=Non
self.name)
elif withStandard != self._schema.with_standard:
raise HedFileError(HedExceptions.BAD_WITH_STANDARD_VERSION,
"When merging two schemas without a schema namespace, " +
"you they must have the same withStandard value.", self.name)
"When merging two schemas without a schema namespace, you they must have the same withStandard value.", self.name)
hed_attributes[hed_schema_constants.VERSION_ATTRIBUTE] = self._schema.version_number + f",{version_number}"
hed_attributes[hed_schema_constants.LIBRARY_ATTRIBUTE] = self._schema.library + f",{self.library}"
if name:
Expand All @@ -71,35 +70,35 @@ def __init__(self, filename, schema_as_string=None, schema=None, file_format=Non
self._schema.header_attributes = hed_attributes
self._loading_merged = False


@property
def schema(self):
""" The partially loaded schema if you are after just header attributes.."""
""" The partially loaded schema if you are after just header attributes."""
return self._schema

@classmethod
def load(cls, filename=None, schema_as_string=None, schema=None, file_format=None, name=""):
""" Load and return the schema, including partnered schema if applicable.
""" Loads and returns the schema, including partnered schema if applicable.
Parameters:
filename(str or None): A valid filepath or None.
schema_as_string(str or None): A full schema as text or None.
schema(HedSchema or None): A HED schema to merge this new file into.
filename(str or None): A valid filepath or None
schema_as_string(str or None): A full schema as text or None
schema(HedSchema or None): A hed schema to merge this new file into
It must be a with-standard schema with the same value.
file_format(str or None): If this is an owl file being loaded, this is the format.
Allowed values include: turtle, json-ld, and owl(xml).
name(str or None): Optional user supplied identifier, by default uses filename.
Allowed values include: turtle, json-ld, and owl(xml)
name(str or None): Optional user supplied identifier, by default uses filename
Returns:
schema(HedSchema): The new schema.
schema(HedSchema): The new schema
"""
loader = cls(filename, schema_as_string, schema, file_format, name)
return loader._load()

def _load(self):
""" Parse the previously loaded data, including loading a partnered schema if needed.
""" Parses the previously loaded data, including loading a partnered schema if needed.
Returns:
schema(HedSchema): The new schema.
schema(HedSchema): The new schema
"""
self._loading_merged = True
# Do a full load of the standard schema if this is a partnered schema
Expand All @@ -126,27 +125,26 @@ def _load(self):

@abstractmethod
def _open_file(self):
""" Overloaded versions should retrieve the input from filename/schema_as_string. """
"""Overloaded versions should retrieve the input from filename/schema_as_string"""
pass

@abstractmethod
def _get_header_attributes(self, input_data):
""" Overloaded versions should return the header attributes from the input data.."""
"""Overloaded versions should return the header attributes from the input data."""
pass

@abstractmethod
def _parse_data(self):
""" Put the input data into the new schema. """
"""Puts the input data into the new schema"""
pass

def _add_to_dict_base(self, entry, key_class):
if not entry.has_attribute(HedKey.InLibrary) and self.appending_to_schema and self._schema.merged:
return None

if self.library and (not self._schema.with_standard or
(not self._schema.merged and self._schema.with_standard)):
if self.library and (not self._schema.with_standard or (not self._schema.merged and self._schema.with_standard)):
# only add it if not already present - This is a rare case
if not entry.has_attribute(HedKey.InLibrary):
entry._set_attribute_value(HedKey.InLibrary, self.library)

return self._schema._add_tag_to_dict(entry.name, entry, key_class)
return self._schema._add_tag_to_dict(entry.name, entry, key_class)
47 changes: 28 additions & 19 deletions hed/schema/schema_io/owl2schema.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Create a HedSchema object from an OWL file or graph.
This module is used to create a HedSchema object from an OWL file or graph.
"""


Expand All @@ -9,18 +9,18 @@
from .base2schema import SchemaLoader
import rdflib
from rdflib.exceptions import ParserError
from rdflib import RDF, RDFS, URIRef, OWL
from rdflib import Graph, RDF, RDFS, Literal, URIRef, OWL, XSD
from collections import defaultdict

from hed.schema.schema_io.owl_constants import HED, HEDT, HEDU, HEDUM


class SchemaLoaderOWL(SchemaLoader):
""" Load XML schemas from filenames or strings.
""" Loads XML schemas from filenames or strings.
Expected usage is SchemaLoaderXML.load(filename).
Expected usage is SchemaLoaderXML.load(filename)
SchemaLoaderXML(filename) will load just the header_attributes.
SchemaLoaderXML(filename) will load just the header_attributes
"""
def __init__(self, filename, schema_as_string=None, schema=None, file_format=None, name=""):
if schema_as_string and not file_format:
Expand All @@ -35,7 +35,7 @@ def __init__(self, filename, schema_as_string=None, schema=None, file_format=Non
self._rooted_cache = {}

def _open_file(self):
""" Parse a Turtle/owl/etc. file and returns the RDF graph. """
"""Parses a Turtle/owl/etc file and returns the RDF graph."""

graph = rdflib.Graph()
try:
Expand All @@ -51,17 +51,17 @@ def _open_file(self):
return graph

def _read_prologue(self):
""" Read the Prologue section from the ontology. """
"""Reads the Prologue section from the ontology."""
prologue = self.graph.value(subject=HED.Prologue, predicate=HED.elementValue, any=False)
return str(prologue) if prologue else ""

def _read_epilogue(self):
""" Read the Epilogue section from the ontology. """
"""Reads the Epilogue section from the ontology."""
epilogue = self.graph.value(subject=HED.Epilogue, predicate=HED.elementValue, any=False)
return str(epilogue) if epilogue else ""

def _get_header_attributes(self, graph):
""" Parse header attributes from an RDF graph into a dictionary. """
"""Parses header attributes from an RDF graph into a dictionary."""
header_attributes = {}
for s, _, _ in graph.triples((None, RDF.type, HED.HeaderMember)):
label = graph.value(s, RDFS.label)
Expand All @@ -77,6 +77,7 @@ def _parse_data(self):
self.graph.bind("hedu", HEDU)
self.graph.bind("hedum", HEDUM)


self._schema.epilogue = self._read_epilogue()
self._schema.prologue = self._read_prologue()
self._get_header_attributes(self.graph)
Expand All @@ -90,7 +91,9 @@ def _parse_data(self):
breakHere = 3

def get_local_names_from_uris(parent_chain, tag_uri):
""" Extract local names from URIs using RDFlib's n3() method. """
"""
Extracts local names from URIs using RDFlib's n3() method.
"""
full_names = []
for uri in parent_chain + [tag_uri]:
# Serialize the URI into N3 format and extract the local name
Expand All @@ -100,18 +103,18 @@ def get_local_names_from_uris(parent_chain, tag_uri):
return full_names

def sort_classes_by_hierarchy(self, classes):
""" Sort all tags based on assembled full name.
"""
Sorts all tags based on assembled full name
Returns:
list of tuples.
Left Tag URI, right side is parent labels(not including self).
Left Tag URI, right side is parent labels(not including self)
"""
parent_chains = []
full_tag_names = []
for tag_uri in classes:
parent_chain = self._get_parent_chain(tag_uri)
parent_chain = [uri.n3(namespace_manager=self.graph.namespace_manager).split(':')[-1]
for uri in parent_chain + [tag_uri]]
parent_chain = [uri.n3(namespace_manager=self.graph.namespace_manager).split(':')[-1] for uri in parent_chain + [tag_uri]]
# parent_chain = [self.graph.value(p, RDFS.label) or p for p in parent_chain + [tag_uri]]
full_tag_names.append("/".join(parent_chain))
parent_chains.append((tag_uri, parent_chain[:-1]))
Expand All @@ -122,7 +125,7 @@ def sort_classes_by_hierarchy(self, classes):
return parent_chains

def _get_parent_chain(self, cls):
""" Recursively build the parent chain for a given class. """
""" Recursively builds the parent chain for a given class. """
parent = self.graph.value(subject=cls, predicate=HED.hasHedParent)
if parent is None:
return []
Expand Down Expand Up @@ -168,23 +171,27 @@ def _parse_uri(self, uri, key_class, name=None):
return tag_entry

def _get_classes_with_subproperty(self, subproperty_uri, base_type):
""" Iterate over all classes that have a specified rdfs:subPropertyOf. """
"""Iterates over all classes that have a specified rdfs:subPropertyOf."""
classes = set()
for s in self.graph.subjects(RDF.type, base_type):
if (s, RDFS.subPropertyOf, subproperty_uri) in self.graph:
classes.add(s)
return classes

def _get_all_subclasses(self, base_type):
""" Recursively find all subclasses of the given base_type. """
"""
Recursively finds all subclasses of the given base_type.
"""
subclasses = set()
for subclass in self.graph.subjects(RDFS.subClassOf, base_type):
subclasses.add(subclass)
subclasses.update(self._get_all_subclasses(subclass))
return subclasses

def _get_classes(self, base_type):
""" Retrieve all instances of the given base_type, including instances of its subclasses. """
"""
Retrieves all instances of the given base_type, including instances of its subclasses.
"""
classes = set()
# Add instances of the base type
for s in self.graph.subjects(RDF.type, base_type):
Expand Down Expand Up @@ -231,6 +238,8 @@ def _read_units(self):
self._add_to_dict(new_entry, key_class)
unit_classes[uri] = new_entry



key_class = HedSectionKey.Units
units = self._get_classes(HED.HedUnit)
for uri in units:
Expand Down Expand Up @@ -265,7 +274,7 @@ def _add_tag_internal(self, uri, parent_tags):
self._add_to_dict(tag_entry, HedSectionKey.Tags)

def _read_tags(self):
""" Populate a dictionary of dictionaries associated with tags and their attributes. """
"""Populates a dictionary of dictionaries associated with tags and their attributes."""
classes = self._get_classes(HED.HedTag)
classes.update(self._get_classes(HED.HedPlaceholder))
sorted_classes = self.sort_classes_by_hierarchy(classes)
Expand Down
3 changes: 2 additions & 1 deletion hed/schema/schema_io/owl_constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
""" OWL constants used to define namespaces. """
from rdflib import Namespace

from hed.schema.hed_schema_constants import HedSectionKey


Expand Down Expand Up @@ -48,3 +48,4 @@
HedSectionKey.UnitModifiers: "HedUnitModifier",
HedSectionKey.ValueClasses: "HedValueClass",
}

28 changes: 16 additions & 12 deletions hed/schema/schema_io/schema2base.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
""" Baseclass for mediawiki/xml writers. """
"""Baseclass for mediawiki/xml writers"""
from hed.schema.hed_schema_constants import HedSectionKey, HedKey
from hed.errors.exceptions import HedFileError, HedExceptions


class Schema2Base:
""" Baseclass for mediawiki/xml writers. """
def __init__(self):
# Placeholder output variable.
# Placeholder output variable
self.output = None
self._save_lib = False
self._save_base = False
Expand All @@ -15,15 +14,20 @@ def __init__(self):

@classmethod
def process_schema(cls, hed_schema, save_merged=False):
""" Take a HedSchema object and return a list of strings representing its .mediawiki version.
Parameters:
hed_schema (HedSchema): The schema to be processed.
save_merged (bool): If True, this will save the schema as a merged schema if it is a "withStandard" schema.
If it is not a "withStandard" schema, this setting has no effect.
Returns:
(Any): Varies based on inherited class.
"""
Takes a HedSchema object and returns a list of strings representing its .mediawiki version.
Parameters
----------
hed_schema : HedSchema
save_merged: bool
If True, this will save the schema as a merged schema if it is a "withStandard" schema.
If it is not a "withStandard" schema, this setting has no effect.
Returns
-------
converted_output: Any
Varies based on inherited class
"""
if not hed_schema.can_save():
Expand Down
Loading

0 comments on commit d8f4a94

Please sign in to comment.