Lets say I want to inspect all calculations (variety of codes used) including gold and copper in my database.
First I tried something like this
query = QueryBuilder()
query.append(StructureData, filters = { 'attributes.kinds': {'contains': ["Au", "Cu"]} }, tag='structure')
query.append(CalcJobNode, with_incoming="structure")
But couldn’t get it to work since kinds
is not a simple list of strings. So I did the following to get it to work quickly.
query = QueryBuilder()
query.append(CalcJobNode)
elements = ["Cu","Au"]
alloy_calcs = []
for calc, in query.iterall():
try:
kind_names = calc.inputs.structure.get_kind_names()
if all(el in kind_names for el in elements):
alloy_calcs.append(calc)
except Exception as e:
print(e)
Is it possible to accomplish this with the QueryBuilder
(maybe similar to my first approach)?
Hi @un1queu5er!
Yes, this is possible. The following should work for you:
from aiida import orm
# Generate the kinds that you want to query
kind1 = orm.Kind(symbols='Au', name='Au')
kind1 = kind1.get_raw()
kind2 = orm.Kind(symbols='Cu', name='Cu')
kind2 = kind2.get_raw()
print(kind1) # This is exactly the type of dict you are looking for in the kinds attribute
# {'symbols': ('Au',), 'weights': (1.0,), 'mass': 196.966569, 'name': 'Au'}
q = orm.QueryBuilder().append(
orm.StructureData, filters={'attributes.kinds': {'contains': [kind1, kind2]}}
)
structures = q.all(flat=True)
# Those are structures that contain Au and Cu
# In my case: AuCu', 'AuCu4Gd', 'C6Au3Cu3N6', 'AuCu4Dy', 'AuCuZn2',
In principle, you don’t need to use the Kind
objects and could simply define the necessary dict
s yourself. I used them, as they automatically insert the mass in the dict resulting from .get_raw()
, so that you don’t have to look it up.
One thing to note: the weights
attribute is set to 1.0 per default. So in case you have structures\kinds with weight unequal to 1, you would need to take this into account.
1 Like