Working with Graph Data
========================

One of the major contributions of *pathology-image-features* is that it is natively set up to import/export/internally use a graph data structure.
This is important because it readily enables specific queries to be made during the course of a computational workflow. It also ensures that output data is traceable back to the processes which were used to generate it.


Serialization
-------------

All classes in *pathology-image-features* have an inherited builtin method "serialize" which takes as input a filepath and (optionally) an rdflib Graph.
This method will create a "Turtle" (RDF/TTL) file containing all of the triples associated with the original object.

After exporting, instances of classes in *pathology-image-features* can be reloaded using the "import_individual" utility function.

.. code-block:: python

    from rdflib import Graph
    from pathology_image_features.utils.general import import_individual

    new_graph = Graph().parse('/path/to/saved/graph.ttl')

    # This will create a new instance of the type of "ExampleObject1234" (iri will be different)
    # with corresponding new instances of any property values which "ExampleObject1234" had.
    new_object_instance = import_individual(
        graph = new_graph,
        iri = 'http://example.org/ExampleObject1234',
        new_instance = True
    )

    # This will create an object with the same IRI and type as "ExampleObject1234", essentially making it
    # identical according to downstream graph operations.
    same_object_instance = import_individual(
        graph = new_graph,
        iri = 'http://example.org/ExampleObject1234',
        new_instance = False
    )


SPARQL queries
--------------

To perform SPARQL queries on the PIFO terms and instances created in a pipeline, use the "query" method on the "PIFO" object.

.. code-block:: python

    from pathology_image_features.ontology import PIFO

    # Print the number of classes.
    print(len(list(PIFO.query('SELECT ?s WHERE { ?t a owl:Class; rdf:type ?s . }'))))

    # Print the number of instances created.
    print(len(list(PIFO.query('SELECT ?s WHERE { ?s a owl:NamedIndividual . }'))))


For more information on working with rdflib Graphs, see the `rdflib documentation <https://rdflib.readthedocs.io/en/stable/>`_.
