Location: SPARC MIS Data Model @ c664f73a3975 / draft02_schema.py

Author:
David Nickerson <david.nickerson@gmail.com>
Date:
2018-11-15 17:55:53+13:00
Desc:
Adding initial attempt at basic provenance classes and properties. * Treating existing 'Resource' class as the core entity as per PROV-O * Adding new 'Agent' and 'Activity' classes * Make the existing 'Researcher' class a subclass of Agent * Adding new 'Software' class as a subclass of the Agent class * Defining the relevant properties to describe the provenance linkages * Software can be described with a text description and/or a URI pointing to the software
Permanent Source URI:
https://models.physiomeproject.org/workspace/526/rawfile/c664f73a3975f999b8369a2bbc02aa9ead9f1329/draft02_schema.py

import owlready2


def load_owl(filename):
    return owlready2.get_ontology("file://" + filename).load()


def map_properties_classes(ontology):
    """
    Return a map of all things
    """

    cls_prop_map = {cls: {} for cls in ontology.classes()}

    for prop in ontology.properties():
        for domain in prop.domain:
            cls = cls_prop_map.get(domain)
            if cls is None:
                continue
            cls[prop] = prop.range

    return cls_prop_map


def to_name(thing):
    if thing is str:
        return 'string'
    return '.'.join(str(thing).split('.')[1:])


def build_property(thing):
    # a very lazy/naive implementation for the mean time.
    if len(thing) == 1:
        if thing[0] is str:
            result = {
                "description": "",
                "type": "string"
            }
        else:
            result = {
                "description": "",
                "type": "model",
                "model": to_name(thing[0])
            }
        return result

    # laziest possible conversion for the unknown case.
    return {"_unknown_type_": str([to_name(item) for item in thing])}


def build_schema(cls_prop_map):
    models = []
    results = {
        "$id": "",
        "$schema": "http://schema.blackfynn.io/model/draft-02/schema",
        "models": models,
    }

    for cls, cls_prop in cls_prop_map.items():
        key, value = build_schema_cls(cls, cls_prop)
        models.append(value)
    return results


def build_schema_cls(cls, cls_prop):
    schema_properties = {}
    schema = {
        "name": to_name(cls),
        "description": "",
        "category": "SPARC",
        "properties": schema_properties,
        "required": [],
        "relationships": [],
    }

    for prop, range_ in cls_prop.items():
        schema_properties[to_name(prop)] = build_property(range_)
    return to_name(cls), schema


if __name__ == '__main__':
    import sys
    import json
    from os.path import basename
    if len(sys.argv) < 2:
        sys.stderr.write('usage: %s <owl_file>\n' % basename(sys.argv[0]))
        sys.exit(1)
    ontology = load_owl(sys.argv[1])
    cls_prop_map = map_properties_classes(ontology)
    schemas = build_schema(cls_prop_map)
    print(json.dumps(schemas, indent=4))