Getting started#

Ontology based atomic structure creation, manipulation, querying.


from pyscal_rdf import StructureGraph

First we create a graph

g = StructureGraph()

Creation of structures#

We will create three structures for the demonstration.

First a BCC Iron structure

struct_Fe = g.create.element.Fe()

Note that when the structure is created, it is also added to the Graph automatically. We can visualise the graph.


Now a Si diamond structure

struct_Si = g.create.element.Si()

Finally, an L12 \(Ni_3 Al\) structure

struct_l12 = g.create.lattice.l12(element=['Al', 'Ni'], 

We can save the graph and reload it as needed

Querying the graph#

An example question would be, what are the space group of all structures with 4 atoms?

The corresponding SPARQL query looks like this:

query = """
PREFIX cmso: <>
    ?sample cmso:hasNumberOfAtoms ?number .
    ?sample cmso:hasMaterial ?material .
    ?material cmso:hasStructure ?structure .
    ?structure cmso:hasSpaceGroupSymbol ?symbol .
FILTER (?number="4"^^xsd:integer)
res = g.query(query)

And print the results


The query system can also be used without experience in SPARQL, or deep knowledge about the ontology terms. For example, What are all the samples with Bravais lattice bcc?

First how this looks like:

res = g.query_sample(g.ontology.terms.cmso.hasAltName, 
UnboundLocalError                         Traceback (most recent call last)
Cell In[11], line 1
----> 1 res = g.query_sample(g.ontology.terms.cmso.hasAltName, 
      2              condition=(g.ontology.terms.cmso.hasAltName=='bcc'))
      3 res

File ~/checkouts/, in RDFGraph.query_sample(self, destination, condition, return_query, enforce_types)
    929 def query_sample(self, destination, condition=None, return_query=False, enforce_types=True):
--> 930     return self.auto_query(self.ontology.terms.cmso.AtomicScaleSample, destination,
    931         condition=condition, return_query=return_query, enforce_types=enforce_types)

File ~/checkouts/, in RDFGraph.auto_query(self, source, destination, condition, return_query, enforce_types)
    916             return res
    917 else:
    918     query = self.ontology.create_query(source, destination, 
--> 919         condition=condition, enforce_types=val)
    920     if return_query:
    921         return query

UnboundLocalError: cannot access local variable 'val' where it is not associated with a value

As expected, there is only one sample, since Fe is the only bcc structure we added. We can extract the sample

sample = res.AtomicScaleSample[0]

We can write this sample to a file, for example, a LAMMPS data format, to use it for further simulations

g.to_file(sample, '', format="lammps-data")
! more (written by ASE) 

2 	 atoms 
1  atom types
0.0      2.8700000000000001  xlo xhi
0.0      2.8700000000000001  ylo yhi
0.0      2.8700000000000001  zlo zhi


     1   1                       0                       0                      
     2   1      1.4350000000000001      1.4350000000000001      1.43500000000000

We can also export as an ASE object

aseobj = g.to_file(sample, format="ase")
Atoms(symbols='Fe2', pbc=True, cell=[2.87, 2.87, 2.87])