Skip to content

Commit

Permalink
Merge pull request #76 from pyscal/improved_workflow_annotation
Browse files Browse the repository at this point in the history
Improved workflow annotation
  • Loading branch information
srmnitc authored Apr 11, 2024
2 parents 5b10810 + 470a7e0 commit d7a5cfa
Show file tree
Hide file tree
Showing 11 changed files with 627 additions and 230 deletions.
2 changes: 1 addition & 1 deletion environment-workflows.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: workflow-rdf-v0.1
name: workflow-rdf-v0.2
channels:
- conda-forge
dependencies:
Expand Down
3 changes: 3 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ dependencies:
- owlready2
- plotly
- ipywidgets
- sqlalchemy
- pip:
- "git+https://github.com/RDFLib/rdflib-sqlalchemy.git@develop"
3 changes: 2 additions & 1 deletion pyscal_rdf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from pyscal_rdf.graph import KnowledgeGraph
from pyscal_rdf.structure import System
from pyscal_rdf.structure import System
from pyscal_rdf.workflow.workflow import Workflow
49 changes: 12 additions & 37 deletions pyscal_rdf/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"""

from rdflib import Graph, Literal, Namespace, XSD, RDF, RDFS, BNode, URIRef, FOAF, SKOS, DCTERMS
from rdflib.store import NO_STORE, VALID_STORE
from rdflib import plugin

import os
import numpy as np
Expand All @@ -26,9 +24,12 @@
from pyscal_rdf.network.ontology import read_ontology
from pyscal_rdf.structure import System
import pyscal_rdf.properties as prp
from pyscal_rdf.stores import create_store

#from pyscal3.core import System
from pyscal3.atoms import Atoms


CMSO = Namespace("http://purls.helmholtz-metadaten.de/cmso/")
PLDO = Namespace("http://purls.helmholtz-metadaten.de/pldo/")
PODO = Namespace("http://purls.helmholtz-metadaten.de/podo/")
Expand Down Expand Up @@ -70,12 +71,6 @@ def _replace_keys(refdict, indict):
refdict[key] = val
return refdict

def _setup_structure_store(structure_store):
if structure_store is None:
structure_store = os.path.join(os.getcwd(), 'rdf_structure_store')
if not os.path.exists(structure_store):
os.mkdir(structure_store)
return structure_store

class KnowledgeGraph:
def __init__(self, graph_file=None,
Expand All @@ -85,36 +80,12 @@ def __init__(self, graph_file=None,
ontology=None,
structure_store=None):

self.store_file = store_file
self.structure_store = structure_store


if store == "Memory":
self.graph = Graph(store="Memory", identifier=identifier)


elif store=="SQLAlchemy":
#check for modules
try:
import sqlalchemy as sa
except ImportError:
raise RuntimeError('Please install the sqlalchemy package')
try:
import rdflib_sqlalchemy as rsa
except ImportError:
raise RuntimeError('Please install the rdllib-sqlalchemy package. The development version is needed, please do pip install git+https://github.com/RDFLib/rdflib-sqlalchemy.git@develop')

if store_file is None:
raise ValueError("store file is needed if store is not memory")

self.graph = Graph(store="SQLAlchemy", identifier=identifier)
uri = Literal(f"sqlite:///{store_file}")
self.graph.open(uri, create=True)
else:
raise ValueError("Memory or SQLAlchemy")

create_store(self, store, identifier,
store_file=store_file,
structure_store=structure_store)

#start the storage
self.structure_store = _setup_structure_store(self.structure_store)

#start binding
self.graph.bind("cmso", CMSO)
Expand All @@ -135,7 +106,11 @@ def __init__(self, graph_file=None,
self._atom_ids = None
self.store = store



def add_structure(self, structure):
structure.graph = self
structure.to_graph()

def add(self, triple):
if str(triple[2].toPython()) != 'None':
self.graph.add(triple)
Expand Down
64 changes: 64 additions & 0 deletions pyscal_rdf/stores.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from rdflib.store import NO_STORE, VALID_STORE
from rdflib import plugin
from rdflib import Graph, Literal

import os
#special methods; for supporting workflow envs
from pyscal_rdf.workflow import inform_graph


def create_store(kg, store, identifier,
store_file=None,
structure_store=None):

kg.store_file = store_file
if store == 'Memory':
store_memory(kg, store, identifier, store_file=store_file, structure_store=structure_store)
elif store == 'SQLAlchemy':
store_alchemy(kg, store, identifier, store_file=store_file, structure_store=structure_store)
elif type(store).__name__ == 'Project':
store_pyiron(kg, store, identifier, store_file=store_file, structure_store=structure_store)
else:
raise ValueError('Unknown store found!')


def store_memory(kg, store, identifier, store_file=None, structure_store=None):
graph = Graph(store="Memory", identifier=identifier)
kg.graph = graph
kg.structure_store = _setup_structure_store(structure_store=structure_store)

def store_alchemy(kg, store, identifier, store_file=None, structure_store=None):
_check_if_sqlalchemy_is_available()
if store_file is None:
raise ValueError("store file is needed if store is not memory")

kg.graph = Graph(store="SQLAlchemy", identifier=identifier)
uri = Literal(f"sqlite:///{store_file}")
kg.graph.open(uri, create=True)
kg.structure_store = _setup_structure_store(structure_store=structure_store)


def store_pyiron(kg, store, identifier, store_file=None, structure_store=None):
structure_store = os.path.join(store.path, 'rdf_structure_store')
kg.structure_store = _setup_structure_store(structure_store=structure_store)
store_file = os.path.join(store.path, f'{store.name}.db')
store_alchemy(kg, store, identifier, store_file, structure_store=structure_store)
#finally update project object
inform_graph(store, kg)

def _check_if_sqlalchemy_is_available():
try:
import sqlalchemy as sa
except ImportError:
raise RuntimeError('Please install the sqlalchemy package')
try:
import rdflib_sqlalchemy as rsa
except ImportError:
raise RuntimeError('Please install the rdllib-sqlalchemy package. The development version is needed, please do pip install git+https://github.com/RDFLib/rdflib-sqlalchemy.git@develop')

def _setup_structure_store(structure_store=None):
if structure_store is None:
structure_store = os.path.join(os.getcwd(), 'rdf_structure_store')
if not os.path.exists(structure_store):
os.mkdir(structure_store)
return structure_store
10 changes: 5 additions & 5 deletions pyscal_rdf/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def _make_crystal(structure,
element=None,
primitive=False,
graph=None,
names=True):
names=False):

atoms, box, sdict = pcs.make_crystal(structure,
lattice_constant=lattice_constant,
Expand Down Expand Up @@ -70,7 +70,7 @@ def _make_general_lattice(positions,
noise = 0,
element=None,
graph=None,
names=True):
names=False):

atoms, box, sdict = pcs.general_lattice(positions,
types,
Expand Down Expand Up @@ -98,7 +98,7 @@ def _make_grain_boundary(axis,
repetitions = (1,1,1),
overlap=0.0,
graph=None,
names=True):
names=False):

gb = GrainBoundary()
gb.create_grain_boundary(axis=axis, sigma=sigma,
Expand Down Expand Up @@ -194,7 +194,7 @@ def __init__(self, filename = None,
species = None,
source=None,
graph=None,
names=True):
names=False):

super().__init__(filename = filename,
format = format,
Expand Down Expand Up @@ -543,7 +543,7 @@ def _add_lattice_properties(self):
"""
data = self.schema.material.crystal_structure.unit_cell.lattice_parameter()
lattice_parameter = URIRef(f'{self._name}_LatticeParameter')
self.graph.add((self.unit_cell, CMSO.hasLatticeParamter, lattice_parameter))
self.graph.add((self.unit_cell, CMSO.hasLatticeParameter, lattice_parameter))
self.graph.add((lattice_parameter, RDF.type, CMSO.LatticeParameter))
self.graph.add((lattice_parameter, CMSO.hasLength_x, Literal(data[0], datatype=XSD.float)))
self.graph.add((lattice_parameter, CMSO.hasLength_y, Literal(data[1], datatype=XSD.float)))
Expand Down
3 changes: 2 additions & 1 deletion pyscal_rdf/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ def visualize_graph(g,
#we collapse sample information
#if cmso.connector is found, only use it is it is cmso.hasCalculated
#all sub sample props, indicated by sample_x_jsjsj will be ignored.
green_list = ["hasCalculatedProperty", "wasCalculatedBy", "hasValue"]
ssplit = string3.split('.')
if (len(ssplit) == 2):
if (ssplit[0] == 'cmso') and (ssplit[1] != "hasCalculatedProperty"):
if (ssplit[0] == 'cmso') and (ssplit[1] not in green_list):
plot = False
if string3 == 'subClassOf':
plot = False
Expand Down
Loading

0 comments on commit d7a5cfa

Please sign in to comment.