I’m working on a new workflow within the aiida-environ module. We want to pass in multiple structures and we aren’t sure how many there will be. My initial thought is to make a list of StructureData objects and then store them as a List. This appears to not be allowed. I see that there is a TrajectoryData object but that species that the number of atoms and species must stay constant. What is the best way to store multiple StructureData objects? I wasn’t quite sure how to look that up in the documentation. Thanks.
When you say “you want to pass in”, I take it you mean you want to pass multiple StructureData nodes as input to some kind of a process, e.g. a calcfunction or WorkChain? These have each a separate solutions.
For process functions (such as a calcfunction) you can use variadic arguments just as in normal Python functions:
from aiida.engine import calcfunction
@calcfunction
def take_multiple_structures(**kwargs):
for link_label, structure in kwargs.items():
# Here `structure` will be a `StructureData`
# Now you can call it with an arbitrary number of structures. Note that the
# keys need to be valid identifiers, so just alphanumeric with underscores.
take_multiple_structures(struc_a=StructureData(), struc_b=StructureData(), etc....)
For WorkChains you would use dynamic input namespaces. These namespace simply declare a type, but don’t have to specify exactly which labels they expect but can take any number. Example:
from aiida.engine import WorkChain
from aiida.orm import StructureData
class SomeWorkChain(WorkChain)
@classmethod
def define(cls, spec):
super().define(spec)
spec.input_namespace('structures', valid_type=StructureData)
spec.outline(cls.do_something)
def do_something(self):
for label, structure in self.inputs.structures.items():
# Here label is again link label and `structure` the `StructureData` passed as inputs
# This would be launched as
inputs = {
'structures': {
'struc_a': StructureData(),
'struc_b': StructureData(),
}
....
}
submit(SomeWorkChain, **inputs