Hi!
I haven’t used AiiDA before. I’m now trying to read some data shared as an AiiDA archive (Materials Cloud Archive). I figured that I can use SqliteZipBackend.create_profile("path/to/archive.aiida") to create a profile for accessing it. This does work to some extent, but some of the nodes within the archive won’t let me read them, failing with ValueError: the user cannot be None exception.
The particular steps I made are:
downloaded the above mentioned aiida archive
installed aiida localy with pip instal aiida
updated the downloaded archive with verdi archive migrate screening.aiida migrated.aiida
in python I’m doing the following:
from aiida.storage.sqlite_zip.backend import SqliteZipBackend
from aiida import orm, load_profile
load_profile(SqliteZipBackend.create_profile("migrated.aiida"))
traj_group = orm.Group.objects.get(label="concatenated_trajectories")
stru_group = orm.Group.objects.get(label="starting_structures")
# this works nicely and gives me an ASE structure:
initial_structure = stru_group.nodes[0].get_ase()
print(initial_structure)
# this also works and returns me a 1D numpy array with MD time values:
times = traj_group.nodes[0].get_times()
print(times[:10])
# however, this fails with the above mentioned exception:
step0_struct = traj_group.nodes[0].get_step_structure(0)
From the traceback, I see that just before this error the user value is accessed via backend.default_user, which apparently is None. Hence, my question is whether there is a way to set up a user for this backend?
Or does this mean I need to import the archive into some profile with a non-read-only backend?..
set up an AiiDA profile with verdi quicksetup or verdi setup;
and then
import the archive with verdi archive import (see here and here for info. Latter case imports directly from archive url but you can also import from a file.)
And then, you can access the data directly in a python script by loading the corresponding profile (here named 'qs'). Something like
from aiida import orm, load_profile
load_profile("qs")
group = orm.load_group(label='test_group')
group_nodes = list(group.nodes)
I am not fully sure if you can create profiles or import archive files directly in python in a straightforward way.
Hi SiLiKhon, great to hear that you are straigt away diving into an existing AiiDA archive and using the SqliteZipBackend. The problem you encounter is that calling Trajectory.get_step_structure is creating a new StructureData instance. Even if you are not storing this, this requires a User instance to be set as the user for that node. But apparently, no default user has been defined, so the code excepts.
Now necessarily, the archive must contain at least one User, because all the nodes are required to have one. I opened the archive as well and confirmed that indeed there is a one user
In [1]: from aiida import orm
In [2]: orm.QueryBuilder().append(orm.User).all(flat=True)
Out[2]: [<aiida.orm.users.User at 0x7f1abbe310d0>]
Now all that we have to do is define the default_user_email on the profile and things now work:
In [1]: from aiida.manage import get_profile
In [2]: profile = get_profile()
In [3]: user = orm.QueryBuilder().append(orm.User).first(flat=True)
In [4]: profile.default_user_email = user.email
In [5]: traj_group = orm.Group.objects.get(label="concatenated_trajectories")
In [6]: step0_struct = traj_group.nodes[0].get_step_structure(0)
In [7]: step0_struct
Out[7]: <StructureData: uuid: a85da7ec-489b-497a-af5f-b0a35af1795f (unstored)>
I think the SqliteZipBackend.create_profile should automatically set a default user given that the archive is required to already have a user and no new users can be created, since it is a read-only backend. I have opened an issue for this on aiida-core. For the time being, you can use the workaround I described above.
Edit: the solution above is ideal if you simply want to explore the data. If you want to start working with the data and create new data, or launch new calculations, then you will need a profile with a real storage backend that is not read-only, and the answer by @eimrek is the one to follow
Thank you @eimrek, @sphuber for the prompt and helpful replies!
@eimrek I was hoping to avoid setting up a full profile. It seems to require to set up a database server backend, which is somewhat cumbersome if I only want to have a look at the data.
@sphuber your suggestion works like a charm, thanks again