The ase development team has created a new database module (https://wiki.fysik.dtu.dk/ase/ase/db/db.html ). In this post, we will examine how to use that in conjunction with jasp
to save calculations to a database. To use this you need the latest version of jasp from http://github.com/jkitchin/jasp .
The idea here is to use the code from http://kitchingroup.cheme.cmu.edu/blog/2014/03/20/Finding-VASP-calculations-in-a-directory-tree/ to add each calculation in that subtree to an ase database. We will use the json format for the database.
import os
from jasp import *
from ase.db import connect
c = connect('vaspdb.json')
def vasp_p(directory):
'returns True if a finished OUTCAR file exists in the current directory, else False'
outcar = os.path.join(directory, 'OUTCAR')
if os.path.exists(outcar):
with open(outcar, 'r') as f:
contents = f.read()
if 'General timing and accounting informations for this job:' in contents:
return True
return False
total_time = 0
for root, dirs, files in os.walk('/home-research/jkitchin/research/rutile-atat'):
for d in dirs:
# compute absolute path to each directory in the current root
absd = os.path.join(root, d)
if vasp_p(absd):
# we found a vasp directory, so we can do something in it.
# here we get the elapsed time from the calculation
with jasp(absd) as calc:
atoms = calc.get_atoms()
calc.results['energy'] = atoms.get_potential_energy()
calc.results['forces'] = atoms.get_forces()
# it is important that this line not be inside the jasp
# context-manager, because c.write writes in the local
# dir.
print c.write(atoms, ['atat']), absd
1 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/0
2 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/1
3 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/10
4 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/11
5 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/12
6 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/13
7 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/14
8 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/15
9 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/16
10 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/17
11 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/2
12 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/3
13 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/4
14 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/5
15 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/59
16 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/6
17 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/66
18 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/7
19 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/73
20 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/74
21 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/78
22 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/8
23 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/9
The result is in this file: vaspdb.json .
We can see the contents of that database like this:
import os
from jasp import *
from ase.db import connect
c = connect('vaspdb.json')
g = c.select() # g is a generator
print g.next()
{u'username': u'jkitchin', u'calculator_name': u'vasp', u'tags': array([0, 0, 0, 0, 0, 0]), u'positions': array([[ 1.382, 1.382, 0. ],
[ 3.145, 3.145, 0. ],
[ 3.646, 0.881, 1.548],
[ 0.881, 3.646, 1.548],
[ 0. , 0. , 0. ],
[ 2.263, 2.263, 1.548]]), u'energy': -44.251496, u'calculator_parameters': {u'incar': {u'doc': u'INCAR parameters', u'prec': u'high', u'nbands': 43, u'sigma': 0.1, u'encut': 350.0}, u'doc': u'JSON representation of a VASP calculation.\n\nenergy is in eV\nforces are in eV/\\AA\nstress is in GPa (sxx, syy, szz, syz, sxz, sxy)\nmagnetic moments are in Bohr-magneton\nThe density of states is reported with E_f at 0 eV.\nVolume is reported in \\AA^3\nCoordinates and cell parameters are reported in \\AA\n\nIf atom-projected dos are included they are in the form:\n{ados:{energy:data, {atom index: {orbital : dos}}}\n', u'potcar': [[u'Ru', u'potpaw_PBE/Ru/POTCAR', u'dee616f2a1e7a5430bb588f1710bfea3001d54ea'], [u'O', u'potpaw_PBE/O/POTCAR', u'9a0489b46120b0cad515d935f44b5fbe3a3b1dfa']], u'input': {u'kpts': array([ 6, 6, 10]), u'reciprocal': False, u'xc': u'PBE', u'kpts_nintersections': None, u'setups': {}, u'txt': u'-', u'gamma': True}, u'atoms': {u'cell': array([[ 4.527, 0. , 0. ],
[ 0. , 4.527, 0. ],
[ 0. , 0. , 3.095]]), u'symbols': [u'O', u'O', u'O', u'O', u'Ru', u'Ru'], u'tags': array([0, 0, 0, 0, 0, 0]), u'pbc': array([ True, True, True], dtype=bool), u'positions': array([[ 1.382, 1.382, 0. ],
[ 3.145, 3.145, 0. ],
[ 3.646, 0.881, 1.548],
[ 0.881, 3.646, 1.548],
[ 0. , 0. , 0. ],
[ 2.263, 2.263, 1.548]])}, u'data': {u'stress': array([ 0.088, 0.088, 0.06 , -0. , -0. , -0. ]), u'doc': u'Data from the output of the calculation', u'volume': 63.43221074143486, u'total_energy': -44.251496, u'forces': array([[-0.024, -0.024, 0. ],
[ 0.024, 0.024, 0. ],
[-0.024, 0.024, 0. ],
[ 0.024, -0.024, 0. ],
[ 0. , 0. , 0. ],
[ 0. , 0. , 0. ]]), u'fermi_level': 5.0374}, u'metadata': {u'date.created': 1395241327.477995, u'uuid': u'7081ee4a-af77-11e3-a6e6-003048f5e49e', u'date.created.ascii': u'Wed Mar 19 11:02:07 2014', u'user.username': u'jkitchin', u'atoms.resort': array([2, 3, 4, 5, 0, 1]), u'user.email': u'jkitchin@andrew.cmu.edu', u'user.fullname': u'John Kitchin', u'O.potential.git_hash': u'9a0489b46120b0cad515d935f44b5fbe3a3b1dfa', u'atoms.tags': array([0, 0, 0, 0, 0, 0]), u'O.potential.path': u'potpaw_PBE/O/POTCAR', u'Ru.potential.path': u'potpaw_PBE/Ru/POTCAR', u'Ru.potential.git_hash': u'dee616f2a1e7a5430bb588f1710bfea3001d54ea'}}, u'cell': array([[ 4.527, 0. , 0. ],
[ 0. , 4.527, 0. ],
[ 0. , 0. , 3.095]]), u'numbers': array([ 8, 8, 8, 8, 44, 44]), u'pbc': array([ True, True, True], dtype=bool), u'timestamp': 14.23343757848325, u'keywords': [u'atat'], u'forces': array([[-0.024, -0.024, 0. ],
[ 0.024, 0.024, 0. ],
[-0.024, 0.024, 0. ],
[ 0.024, -0.024, 0. ],
[ 0. , 0. , 0. ],
[ 0. , 0. , 0. ]]), 'id': 1, u'unique_id': u'123901e31734f14418381a23d1ee1072'}
The data stored there comes from the calc.todict() function written for jasp.
We can do some searches like this. Say we want to find all the calculations where there are four oxygen atoms.
import os
from jasp import *
from ase.db import connect
c = connect('vaspdb.json')
g = c.select(O=4) # g is a generator
for entry in g:
print c.get_atoms(entry['id']), '\n'
Atoms(symbols='O4Ru2', positions=..., tags=...,
cell=[4.526933343669885, 4.526933343669885, 3.095292162609941],
pbc=[True, True, True], calculator=SinglePointCalculator(...))
Atoms(symbols='O4Ti2', positions=..., tags=...,
cell=[4.614336091353763, 4.614336091353763, 2.9555779409837473],
pbc=[True, True, True], calculator=SinglePointCalculator(...))
Atoms(symbols='O4RuTi', positions=..., tags=...,
cell=[[-0.0151920891931803, -4.604112035041115, 0.0],
[-4.604112035041115, -0.0151920891931803, 0.0], [0.0, 0.0,
-3.0110141191854245]], pbc=[True, True, True],
calculator=SinglePointCalculator(...))
You can see there are three calculations with that criterion.
1 The command-line interface
There is also a command-line interface.
usage: ase-db [-h] [-n] [-c COLUMNS] [--explain] [-y] [-i INSERT_INTO]
[-k ADD_KEYWORDS] [-K ADD_KEY_VALUE_PAIRS]
[--delete-keywords DELETE_KEYWORDS]
[--delete-key-value-pairs DELETE_KEY_VALUE_PAIRS] [--delete]
[-v] [-q] [-s SORT] [-r] [-l] [--limit LIMIT]
[-p PYTHON_EXPRESSION]
name [selection]
positional arguments:
name
selection
optional arguments:
-h, --help show this help message and exit
-n, --count
-c COLUMNS, --columns COLUMNS
short/long+row-row
--explain
-y, --yes
-i INSERT_INTO, --insert-into INSERT_INTO
-k ADD_KEYWORDS, --add-keywords ADD_KEYWORDS
-K ADD_KEY_VALUE_PAIRS, --add-key-value-pairs ADD_KEY_VALUE_PAIRS
--delete-keywords DELETE_KEYWORDS
--delete-key-value-pairs DELETE_KEY_VALUE_PAIRS
--delete
-v, --verbose
-q, --quiet
-s SORT, --sort SORT
-r, --reverse
-l, --long
--limit LIMIT
-p PYTHON_EXPRESSION, --python-expression PYTHON_EXPRESSION
It is not obvious all those options are actually supported. For example, it is not clear there is a function that actually deletes keywords in the source code. You can add keywords, but I cannot figure out the syntax to add to one entry.
Below are some examples that do work. We can list details of the calculation with id=1.
id|age|user |formula|calc| energy| fmax|pbc| size|keywords| mass
1|9m |jkitchin|O4Ru2 |vasp|-44.251|0.033|111|63.432|atat |266.138
Get calculations with four oxygen atoms:
id|age|user |formula|calc| energy| fmax|pbc| size|keywords| mass
1|9m |jkitchin|O4Ru2 |vasp|-44.251|0.033|111|63.432|atat |266.138
2|9m |jkitchin|O4Ti2 |vasp|-52.970|0.033|111|62.930|atat |159.758
11|9m |jkitchin|O4RuTi |vasp|-48.115|0.157|111|63.826|atat |212.948
Get all calculations tagged with atat
id|age|user |formula |calc| energy| fmax|pbc| size|keywords| mass
1|9m |jkitchin|O4Ru2 |vasp| -44.251|0.033|111| 63.432|atat |266.138
2|9m |jkitchin|O4Ti2 |vasp| -52.970|0.033|111| 62.930|atat |159.758
3|9m |jkitchin|O8Ru2Ti2 |vasp| -96.601|0.086|111|126.719|atat |425.895
4|9m |jkitchin|O8RuTi3 |vasp|-100.842|0.075|111|126.846|atat |372.705
5|9m |jkitchin|O8Ru3Ti |vasp| -92.376|0.133|111|127.420|atat |479.085
6|9m |jkitchin|O8Ru2Ti2 |vasp| -96.594|0.184|111|127.176|atat |425.895
7|9m |jkitchin|O8RuTi3 |vasp|-100.959|0.176|111|126.924|atat |372.705
8|9m |jkitchin|O8Ru3Ti |vasp| -92.314|0.084|111|127.377|atat |479.085
9|9m |jkitchin|O8Ru2Ti2 |vasp| -96.612|0.086|111|126.542|atat |425.895
10|9m |jkitchin|O8RuTi3 |vasp|-100.816|0.080|111|126.557|atat |372.705
11|9m |jkitchin|O4RuTi |vasp| -48.115|0.157|111| 63.826|atat |212.948
12|9m |jkitchin|O8Ru3Ti |vasp| -92.429|0.163|111|127.291|atat |479.085
13|9m |jkitchin|O8Ru2Ti2 |vasp| -96.770|0.166|111|126.870|atat |425.895
14|9m |jkitchin|O8RuTi3 |vasp|-101.014|0.222|111|126.881|atat |372.705
15|9m |jkitchin|O12Ru4Ti2|vasp|-140.969|0.114|111|190.614|atat |692.033
16|9m |jkitchin|O8Ru3Ti |vasp| -92.323|0.125|111|127.541|atat |479.085
17|9m |jkitchin|O12Ru2Ti4|vasp|-149.516|0.241|111|190.070|atat |585.653
18|9m |jkitchin|O8Ru2Ti2 |vasp| -96.661|0.064|111|127.038|atat |425.895
19|9m |jkitchin|O12Ru4Ti2|vasp|-140.472|0.138|111|190.640|atat |692.033
20|9m |jkitchin|O12Ru3Ti3|vasp|-144.667|0.166|111|190.604|atat |638.843
21|9m |jkitchin|O12Ru2Ti4|vasp|-148.813|0.055|111|190.084|atat |585.653
22|9m |jkitchin|O8RuTi3 |vasp|-100.874|0.051|111|126.690|atat |372.705
23|9m |jkitchin|O8Ru3Ti |vasp| -92.246|0.102|111|127.383|atat |479.085
2 Summary thoughts
This is a nice addition to ase. I think it needs some thorough, production work testing to find out exactly how useful it is. We may need to reconsider the calc.todict() function in jasp to remove redundancy, but overall this is a good idea.
Copyright (C) 2014 by John Kitchin. See the License for information about copying.
org-mode source
Org-mode version = 8.2.5h