<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <atom:link href="http://kitchingroup.cheme.cmu.edu/blog/feed/index.xml" rel="self" type="application/rss+xml" />
    <title>The Kitchin Research Group</title>
    <link>https://kitchingroup.cheme.cmu.edu/blog</link>
    <description>Chemical Engineering at Carnegie Mellon University</description>
    <pubDate>Sat, 01 Nov 2025 13:47:46 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    
    <item>
      <title>A prototype implementation of jasp in emacs-lisp</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2014/12/24/A-prototype-implementation-of-jasp-in-emacs-lisp</link>
      <pubDate>Wed, 24 Dec 2014 11:41:00 EST</pubDate>
      <category><![CDATA[lisp]]></category>
      <category><![CDATA[emacs]]></category>
      <category><![CDATA[ase]]></category>
      <category><![CDATA[vasp]]></category>
      <guid isPermaLink="false">GB14oL8NufR3GRSfetF6V-_v3KU=</guid>
      <description>A prototype implementation of jasp in emacs-lisp</description>
      <content:encoded><![CDATA[


&lt;div id="table-of-contents"&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;div id="text-table-of-contents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#sec-1"&gt;1. The Atom class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-2"&gt;2. The Atoms class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-3"&gt;3. The Calculator class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-4"&gt;4. Putting it all together to run calculations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-5"&gt;5. Summary thoughts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
I want to try implementing an interface to &lt;a href="http://www.vasp.at"&gt;VASP&lt;/a&gt; in emacs-lisp. VASP is a program that uses density functional theory to calculate properties of materials. VASP was designed for the user to create several text-based input files that contain an atomic geometry, and calculation parameters. Then you run the VASP program, which reads those input files and generates output files. Finally, you parse out the results you want from the output files. 
&lt;/p&gt;

&lt;p&gt;
It is moderately tedious to do that, so we already have a very extensive Python interface (&lt;a href="http://github.com/jkitchin/jasp"&gt;http://github.com/jkitchin/jasp&lt;/a&gt; ) that automates the input file creation and output file parsing, and with org-mode we have a pretty good literate research environment to document what we do. But, the Python/emacs environment is not as integrated as the emacs-lisp/emacs environment is, particularly when it comes to accessing documentation. So, I want to try out a lisp approach to see what this would look like, and if it has any benefits.
&lt;/p&gt;

&lt;p&gt;
The bare bones implementation will have an Atom object, to store the type of atom and its coordinates, an Atoms object which will be a collection of atoms, and a unit cell, and a Calculator object that will store calculation parameters.
&lt;/p&gt;

&lt;p&gt;
Then, we will try using it to see what advantages it might have. This will be a moderately long post.
&lt;/p&gt;

&lt;div id="outline-container-sec-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;&lt;span class="section-number-2"&gt;1&lt;/span&gt; The Atom class&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-1"&gt;
&lt;p&gt;
This is my first serious effort to use the &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eieio/"&gt;object system&lt;/a&gt; in emacs-lisp, so I do not claim it is optimal, or beautiful. It is functional though. We make a simple Atom class that holds the chemical symbol, and xyz coordinates. We do not consider having a magnetic moment at this point, and this class has no methods.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;defclass&lt;/span&gt; &lt;span style="color: #4682b4;"&gt;Atom&lt;/span&gt; ()
  ((symbol &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt;
           &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"A string for the chemical symbol"&lt;/span&gt;)
   (x &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt;
      &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"The x coordinate"&lt;/span&gt;)
   (y &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt;
      &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"The y coordinate"&lt;/span&gt;)
   (z &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt;
      &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"The z coordinate"&lt;/span&gt;))
 &lt;span style="color: #228b22;"&gt;"A class to represent an atom."&lt;/span&gt;)

(&lt;span style="color: #8b0000;"&gt;provide&lt;/span&gt; '&lt;span style="color: #cd0000;"&gt;Atom&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Atom
&lt;/pre&gt;

&lt;p&gt;
Let us try it out. We make an Atom, then get the symbol using the oref function. I don't think we need a "Name" for the atom, so the second argument is nil.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[object Atom nil "C" 0 0 0]
&lt;/pre&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((a1 (Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0  &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)))
  (oref a1 symbol))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
C
&lt;/pre&gt;

&lt;p&gt;
It is not difficult to modify an Atom object. We use oset.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((a1 (Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0  &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)))
  (oset a1 x 2.5)
  a1)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[object Atom nil "C" 2.5 0 0]
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-sec-2" class="outline-2"&gt;
&lt;h2 id="sec-2"&gt;&lt;span class="section-number-2"&gt;2&lt;/span&gt; The Atoms class&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-2"&gt;
&lt;p&gt;
We need at Atoms object, which will store a list of Atom objects, and a unit cell. I do not know how to make this class act like a list the way that the Atoms object in ase acts. We will have to access the list of atoms as a slot. We define one method here to get the ith atom from the object.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;defclass&lt;/span&gt; &lt;span style="color: #4682b4;"&gt;Atoms&lt;/span&gt; ()
  ((atoms &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt;
          &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"A list of `&lt;/span&gt;&lt;span style="color: #cd0000;"&gt;Atom&lt;/span&gt;&lt;span style="color: #228b22;"&gt;' objects"&lt;/span&gt;)
   (cell &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt;
         &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"A 3-tuple of lengths of an orthorhombic unit cell"&lt;/span&gt;))
  &lt;span style="color: #228b22;"&gt;"A class to represent an atoms object."&lt;/span&gt;)


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;get-atom&lt;/span&gt; ((atoms Atoms) &lt;span style="color: #4682b4;"&gt;&amp;amp;rest&lt;/span&gt; args)
  &lt;span style="color: #228b22;"&gt;"Get a list of atoms in ARGS.&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;Return atom if ARGS contains one element, a list of atom objects&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;otherwise."&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;cond&lt;/span&gt;
   ((= 1 (length args))
    (elt (oref atoms atoms) (car args)))
   (t
    (mapcar (&lt;span style="color: #8b0000;"&gt;lambda&lt;/span&gt; (i)
              (elt (oref atoms atoms) i))
            args))))

(&lt;span style="color: #8b0000;"&gt;provide&lt;/span&gt; '&lt;span style="color: #cd0000;"&gt;Atoms&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
get-atom
&lt;/pre&gt;

&lt;p&gt;
That seems to do what we need. It has some limitations:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;We only allowed for orthorhombic unit cells
&lt;/li&gt;
&lt;li&gt;We did not enable any constraints or magnetic moments on the atoms.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Here is an example Atoms object. Note we use `, notation to ensure each Atom is created, since Atom is a constructor function that returns the object.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(Atoms nil
       &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; `(,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
                ,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 1.1 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0))
       &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt; '(8 9 10))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[object Atoms nil ([object Atom nil "C" 0 0 0] [object Atom nil "O" 1.1 0 0]) (8 9 10)]
&lt;/pre&gt;

&lt;p&gt;
We can drill into the object, e.g. to get the second atom:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((A1 (Atoms nil
                 &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; `(,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
                          ,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 1.1 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0))
                 &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt; '(8 9 10))))
  (get-atom A1 1))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[object Atom nil "O" 1.1 0 0]
&lt;/pre&gt;

&lt;p&gt;
We can modify the atoms in place like this. Suppose we want to change the symbol of the first atom to "O". We use setf for this too.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((A1 (Atoms nil
                 &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; `(,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
                          ,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 1.1 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0))
                 &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt; '(8 9 10))))
  (oset (get-atom A1 0) symbol &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt;)
  A1)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[object Atoms nil ([object Atom nil "O" 0 0 0] [object Atom nil "O" 1.1 0 0]) (8 9 10)]
&lt;/pre&gt;

&lt;p&gt;
The only think I do not like about this syntax is the need to get the list of atoms from the object. That is a little clunkier than the Python analog where the object is a list itself. That may be just my inexperience with emacs-lisp. Probably you can define some getter function to smooth this over.
&lt;/p&gt;

&lt;p&gt;
This Atoms class lacks much of the functionality of the &lt;a href="https://wiki.fysik.dtu.dk/ase/ase/atoms.html"&gt;ase.Atoms&lt;/a&gt; class, but it is sufficient for this prototype.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-sec-3" class="outline-2"&gt;
&lt;h2 id="sec-3"&gt;&lt;span class="section-number-2"&gt;3&lt;/span&gt; The Calculator class&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-3"&gt;
&lt;p&gt;
Next, we need our Calculator. This will store the parameters, and be responsible for creating the INCAR, POSCAR, KPOINTS, and POTCAR files, running a calculation, and getting data from the output. We also create a with-current-directory macro that will temporarily change the working directory since VASP uses the same filenames over and over, but in different directories. 
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;defmacro&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;with-current-directory&lt;/span&gt; (directory &lt;span style="color: #4682b4;"&gt;&amp;amp;rest&lt;/span&gt; body)
  &lt;span style="color: #228b22;"&gt;"Set the working directory temporarily set to DIRECTORY and run BODY.&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;DIRECTORY is expanded, and create it and its parents if needed."&lt;/span&gt;
  `(&lt;span style="color: #8b0000;"&gt;progn&lt;/span&gt;
     (&lt;span style="color: #8b0000;"&gt;unless&lt;/span&gt; (file-exists-p (file-name-as-directory
                             (expand-file-name ,directory)))
       (make-directory ,directory t))
     
     (&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((default-directory (file-name-as-directory
                                (expand-file-name ,directory)))) 
        ,@body)))


(&lt;span style="color: #8b0000;"&gt;defclass&lt;/span&gt; &lt;span style="color: #4682b4;"&gt;Jasp&lt;/span&gt; ()
  ((wd &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:wd&lt;/span&gt;
       &lt;span style="color: #cd0000;"&gt;:initform&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"."&lt;/span&gt;  ; &lt;span style="color: #ff0000; font-weight: bold;"&gt;default to the current working directory&lt;/span&gt;
       &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"Directory to run calculation in."&lt;/span&gt;)
   (encut &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:encut&lt;/span&gt;
          &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"Positive number in eV for planewave cutoff.&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;See URL `&lt;/span&gt;&lt;span style="color: #cd0000;"&gt;http://cms.mpi.univie.ac.at/vasp/vasp/ENCUT_tag.html&lt;/span&gt;&lt;span style="color: #228b22;"&gt;'."&lt;/span&gt;)
   (nbands &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:nbands&lt;/span&gt;
           &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"Integer number of bands.&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;See URL `&lt;/span&gt;&lt;span style="color: #cd0000;"&gt;http://cms.mpi.univie.ac.at/vasp/vasp/NBANDS_tag.html&lt;/span&gt;&lt;span style="color: #228b22;"&gt;'."&lt;/span&gt;)
   (kpts &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:kpts&lt;/span&gt;
         &lt;span style="color: #cd0000;"&gt;:initform&lt;/span&gt; (1 1 1)  ; &lt;span style="color: #ff0000; font-weight: bold;"&gt;default value&lt;/span&gt;
         &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"3-tuple for Monkhorst-Pack K-point grid."&lt;/span&gt;)
   (xc &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:xc&lt;/span&gt;
       &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"String of exchange correlation functional."&lt;/span&gt;)
   (atoms &lt;span style="color: #cd0000;"&gt;:initarg&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt;
          &lt;span style="color: #cd0000;"&gt;:documentation&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"An `&lt;/span&gt;&lt;span style="color: #cd0000;"&gt;Atoms&lt;/span&gt;&lt;span style="color: #228b22;"&gt;' object."&lt;/span&gt;))
 &lt;span style="color: #228b22;"&gt;"A class to represent a calculator that runs VASP."&lt;/span&gt;)


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;view-atoms&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Open the ase-gui"&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;unless&lt;/span&gt; (and (file-exists-p &lt;span style="color: #228b22;"&gt;"POSCAR"&lt;/span&gt;)
               (file-exists-p &lt;span style="color: #228b22;"&gt;"POTCAR"&lt;/span&gt;))
    (write-poscar calc)
    (write-potcar calc))
  (shell-command &lt;span style="color: #228b22;"&gt;"ase-gui POSCAR"&lt;/span&gt;))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;write-poscar&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"create a POSCAR file for CALC."&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;with-temp-file&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"POSCAR"&lt;/span&gt;
    (insert &lt;span style="color: #228b22;"&gt;"Created by jasp.el\n"&lt;/span&gt;)
    (insert &lt;span style="color: #228b22;"&gt;"  1.0"&lt;/span&gt;) ; &lt;span style="color: #ff0000; font-weight: bold;"&gt;unit cell scale factor&lt;/span&gt;
    (&lt;span style="color: #8b0000;"&gt;let*&lt;/span&gt; ((atoms (oref calc atoms))
           (cell (oref atoms cell)))
      (loop for v in cell
            for i below (length cell)     
            do
            (insert &lt;span style="color: #228b22;"&gt;"\n"&lt;/span&gt;)
            (loop for j below (length cell)
                  do
                  (&lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; (equal i j)
                      (insert (format &lt;span style="color: #228b22;"&gt;" %f "&lt;/span&gt; (float (elt cell i))))
                    (insert (format &lt;span style="color: #228b22;"&gt;" %f "&lt;/span&gt; 0.0 ))))))
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;The next line is counts for each atom type. For each number in&lt;/span&gt;
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;this line, there will be a copy of the POTCAR in the POTCAR&lt;/span&gt;
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;file. In ase, we sort the atoms and group them so that there is&lt;/span&gt;
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;only one POTCAR per atom. We do not do that here yet. We will&lt;/span&gt;
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;have a POTCAR for each atom.&lt;/span&gt;
    (insert &lt;span style="color: #228b22;"&gt;"\n"&lt;/span&gt;)
    (loop for atom in (oref (oref calc atoms) atoms)
          do (insert (format &lt;span style="color: #228b22;"&gt;"1 "&lt;/span&gt;)))
    
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;now we do the atoms&lt;/span&gt;
    (insert &lt;span style="color: #228b22;"&gt;"\nCartesian\n"&lt;/span&gt;)
    (loop for atom in (oref (oref calc atoms) atoms)
          do
          (insert
           (format &lt;span style="color: #228b22;"&gt;"%f %f %f\n"&lt;/span&gt;
                   (oref atom x)
                   (oref atom y)
                   (oref atom z))))
    (buffer-string)))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;write-kpoints&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Create KPOINTS file for CALC. &lt;/span&gt;
&lt;span style="color: #228b22;"&gt;Limited to automatic generation, and no offset."&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;with-temp-file&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"KPOINTS"&lt;/span&gt;
    (insert &lt;span style="color: #228b22;"&gt;"Automatic mesh&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;0&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;Monkhorst-Pack&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;"&lt;/span&gt;)
    (&lt;span style="color: #8b0000;"&gt;dolist&lt;/span&gt; (k (oref calc kpts))
      (insert (format &lt;span style="color: #228b22;"&gt;"%4d "&lt;/span&gt; k)))
    (insert &lt;span style="color: #228b22;"&gt;"\n0.0 0.0 0.0"&lt;/span&gt;)
    (buffer-string)))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;write-potcar&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Generate the POTCAR file for CALC.&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;No `&lt;/span&gt;&lt;span style="color: #cd0000;"&gt;Atom&lt;/span&gt;&lt;span style="color: #228b22;"&gt;' grouping is done, there is one POTCAR for each atom."&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;with-temp-file&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"POTCAR"&lt;/span&gt;
    (&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((xc (oref calc xc))
          (atoms (oref calc atoms))
          (vasp_pp_path (getenv &lt;span style="color: #228b22;"&gt;"VASP_PP_PATH"&lt;/span&gt;)))
      (loop for atom in (oref atoms atoms)
            do
            (insert-file-contents
             (f-join
              vasp_pp_path
              (concat &lt;span style="color: #228b22;"&gt;"potpaw_"&lt;/span&gt; xc)
              (oref atom symbol)
              &lt;span style="color: #228b22;"&gt;"POTCAR"&lt;/span&gt;))))
    (buffer-string)))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;write-incar&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Generate the INCAR file for CALC."&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;with-temp-file&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"INCAR"&lt;/span&gt;
    (insert (format &lt;span style="color: #228b22;"&gt;"ENCUT = %f\n"&lt;/span&gt; (oref calc encut)))
    (insert (format &lt;span style="color: #228b22;"&gt;"NBANDS = %d\n"&lt;/span&gt; (oref calc nbands)))
    (buffer-string)))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;run&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Write out input files, and run VASP as a simple shell command"&lt;/span&gt;
  (write-poscar calc)
  (write-kpoints calc)
  (write-potcar calc)
  (write-incar calc)
  (shell-command &lt;span style="color: #228b22;"&gt;"vasp"&lt;/span&gt;))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;update&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Run vasp if needed for CALC.&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;We just check for a properly ended OUTCAR."&lt;/span&gt;
  (with-current-directory
   (oref calc wd)
   (&lt;span style="color: #8b0000;"&gt;unless&lt;/span&gt; (and (file-exists-p &lt;span style="color: #228b22;"&gt;"OUTCAR"&lt;/span&gt;)
                (&lt;span style="color: #8b0000;"&gt;with-temp-buffer&lt;/span&gt;
                  (insert-file-contents &lt;span style="color: #228b22;"&gt;"OUTCAR"&lt;/span&gt;)
                  (re-search-forward
                  &lt;span style="color: #228b22;"&gt;"                 Voluntary context switches:"&lt;/span&gt;
                  (point-max)
                  t)))
     (run calc))))


(&lt;span style="color: #8b0000;"&gt;defmethod&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;get-potential-energy&lt;/span&gt; ((calc Jasp))
  &lt;span style="color: #228b22;"&gt;"Get potential energy from CALC."&lt;/span&gt;
  (update calc)
  (with-current-directory
   (oref calc wd)
   (&lt;span style="color: #8b0000;"&gt;with-temp-buffer&lt;/span&gt;
     (insert-file-contents &lt;span style="color: #228b22;"&gt;"OUTCAR"&lt;/span&gt;)
     ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;go to last entry&lt;/span&gt;
     (&lt;span style="color: #8b0000;"&gt;while&lt;/span&gt; (re-search-forward
             &lt;span style="color: #228b22;"&gt;"free  energy   TOTEN  =\\s-*&lt;/span&gt;&lt;span style="color: #228b22;"&gt;\\&lt;/span&gt;&lt;span style="color: #228b22;"&gt;(&lt;/span&gt;&lt;span style="color: #228b22;"&gt;[-]?[0-9]*\\.[0-9]*&lt;/span&gt;&lt;span style="color: #228b22;"&gt;\\&lt;/span&gt;&lt;span style="color: #228b22;"&gt;)&lt;/span&gt;&lt;span style="color: #228b22;"&gt; eV"&lt;/span&gt;
             (point-max)
             t)
       nil)
     ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;return last match&lt;/span&gt;
     (string-to-number  (match-string 1)))))

(&lt;span style="color: #8b0000;"&gt;provide&lt;/span&gt; '&lt;span style="color: #cd0000;"&gt;jasp&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
get-potential-energy
&lt;/pre&gt;


&lt;p&gt;
This is worth some discussion. On one hand, the constructor is a bit more verbose than the implementation in Python. In Python we use a context handler in place of the macro here. On the other hand, that verbosity comes with detailed, accessible documentation for each argument. We only considered the simplest of input arguments. It might be trickier to include lists, and other types of input. But I think those can all be worked out like they were in ase. We only implemented the simplest job control logic, but that also can be worked out. The biggest challenge might be getting more complex data from the output. Nearly everything can be obtained from vasprun.xml also, in the event that parsing is to slow or difficult.
&lt;/p&gt;

&lt;p&gt;
Now, let us test this out. We can make a calculator:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(setq calc (Jasp
            nil
            &lt;span style="color: #cd0000;"&gt;:xc&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"PBE"&lt;/span&gt;
            &lt;span style="color: #cd0000;"&gt;:encut&lt;/span&gt; 350
            &lt;span style="color: #cd0000;"&gt;:nbands&lt;/span&gt; 6
            &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; (Atoms
                    nil
                    &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; `(,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
                             ,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 1.1 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0))
                    &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt; '(8 9 10))))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[object Jasp nil "." 350 6 (1 1 1) "PBE" [object Atoms nil ([object Atom nil "C" 0 0 0] [object Atom nil "O" 1.1 0 0]) (8 9 10)]]
&lt;/pre&gt;

&lt;p&gt;
We can call the class functions like this. Here we write out the corresponding POSCAR:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(write-poscar calc)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Created by jasp.el
  1.0
 8.000000  0.000000  0.000000 
 0.000000  9.000000  0.000000 
 0.000000  0.000000  10.000000 
1 1 
Cartesian
0.000000 0.000000 0.000000
1.100000 0.000000 0.000000
&lt;/pre&gt;

&lt;p&gt;
It looks a little backward if you have only seen Python, where this would be calc.write&lt;sub&gt;poscar&lt;/sub&gt;(). It is almost the same characters, just a different order (and no . in lisp)!
&lt;/p&gt;

&lt;p&gt;
Here we get the KPOINTS file:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(write-kpoints calc)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Automatic mesh
0
Monkhorst-Pack
   1    1    1 
0.0 0.0 0.0
&lt;/pre&gt;


&lt;p&gt;
I cannot show the POTCAR file for licensing reasons, but it works.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(write-potcar calc)
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
and the INCAR file:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(write-incar calc)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
ENCUT = 350.000000
NBANDS = 6
&lt;/pre&gt;

&lt;p&gt;
We run a calculation like this. This will run vasp directly (not through the queue system). 
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(run calc)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
0
&lt;/pre&gt;

&lt;p&gt;
The returned 0 means the shell command finished correctly.
&lt;/p&gt;

&lt;p&gt;
And we retrieve the potential energy like this:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(get-potential-energy calc)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
-14.687906
&lt;/pre&gt;

&lt;p&gt;
Not bad. That is close to the result we got from a similar calculation &lt;a href="http://kitchingroup.cheme.cmu.edu/dft-book/dft.html#sec-3-3-1"&gt;here&lt;/a&gt; . 
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-sec-4" class="outline-2"&gt;
&lt;h2 id="sec-4"&gt;&lt;span class="section-number-2"&gt;4&lt;/span&gt; Putting it all together to run calculations&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-4"&gt;
&lt;p&gt;
If we put this all together the way we might use it in practice, it looks like this. 
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(load-file &lt;span style="color: #228b22;"&gt;"Atom.el"&lt;/span&gt;)
(load-file &lt;span style="color: #228b22;"&gt;"Atoms.el"&lt;/span&gt;)
(load-file &lt;span style="color: #228b22;"&gt;"Jasp.el"&lt;/span&gt;)

(&lt;span style="color: #8b0000;"&gt;let*&lt;/span&gt; ((co (Atoms
            nil
            &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; `(,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
                     ,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 1.1 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0))
            &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt; '(8 9 10)))

       (calc (Jasp
              nil
              &lt;span style="color: #cd0000;"&gt;:xc&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"PBE"&lt;/span&gt;
              &lt;span style="color: #cd0000;"&gt;:nbands&lt;/span&gt; 6
              &lt;span style="color: #cd0000;"&gt;:encut&lt;/span&gt; 350
              &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; co)))
  
  (get-potential-energy calc))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
-14.687906
&lt;/pre&gt;

&lt;p&gt;
Compare this with this Python code which does approximately the same thing:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; Atoms, Atom
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *

&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;co&lt;/span&gt; = Atoms([Atom(&lt;span style="color: #228b22;"&gt;'C'&lt;/span&gt;, [&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;0&lt;/span&gt;,   &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;0&lt;/span&gt;, &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;0&lt;/span&gt;]),
            Atom(&lt;span style="color: #228b22;"&gt;'O'&lt;/span&gt;, [&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;1&lt;/span&gt;.&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;1&lt;/span&gt;, &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;0&lt;/span&gt;, &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;0&lt;/span&gt;])],
            &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;cell&lt;/span&gt;=(&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;6&lt;/span&gt;., &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;6&lt;/span&gt;., &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;6&lt;/span&gt;.))

&lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; jasp(&lt;span style="color: #228b22;"&gt;'molecules/simple-co'&lt;/span&gt;, &lt;span style="color: #ff0000; font-weight: bold;"&gt;#output dir&lt;/span&gt;
          &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;xc&lt;/span&gt;=&lt;span style="color: #228b22;"&gt;'PBE'&lt;/span&gt;,  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# the exchange-correlation functional&lt;/span&gt;
          &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;nbands&lt;/span&gt;=&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;6&lt;/span&gt;,  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# number of bands&lt;/span&gt;
          &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;encut&lt;/span&gt;=&lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;350&lt;/span&gt;, &lt;span style="color: #ff0000; font-weight: bold;"&gt;# planewave cutoff&lt;/span&gt;
          &lt;span style="color: #000000; background-color: #cccccc; font-weight: bold;"&gt;atoms&lt;/span&gt;=co) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; calc:
    &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'energy = {0} eV'&lt;/span&gt;.format(co.get_potential_energy())
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
They look pretty similar. One thing clearly missing from emacs-lisp that Python has is full support for numerics and plotting. Some of this could be addressed via &lt;a href="http://kitchingroup.cheme.cmu.edu/blog/2014/10/19/Using-Pymacs-to-integrate-Python-into-Emacs/"&gt;Pymacs&lt;/a&gt; , but certainly not all of it. Some of it could also be handled using org-mode to enable data from emacs-lisp to go to other code blocks that can handle it. 
&lt;/p&gt;

&lt;p&gt;
Finally, for a little fun, we illustrate mapping over a range of bond lengths. There is more than one way to do this. For example, we could create a list of calculators, and then run over them. Here we create one calculator, and just change the x position in a loop. We use the more general setf approach instead of oset to see what it looks like.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let*&lt;/span&gt; ((co (Atoms
            nil
            &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; `(,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"C"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0)
                     ,(Atom nil &lt;span style="color: #cd0000;"&gt;:symbol&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"O"&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;:x&lt;/span&gt; 1.1 &lt;span style="color: #cd0000;"&gt;:y&lt;/span&gt; 0 &lt;span style="color: #cd0000;"&gt;:z&lt;/span&gt; 0))
            &lt;span style="color: #cd0000;"&gt;:cell&lt;/span&gt; '(8 9 10)))
       (calc (Jasp
              nil
              &lt;span style="color: #cd0000;"&gt;:wd&lt;/span&gt; nil
              &lt;span style="color: #cd0000;"&gt;:xc&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"PBE"&lt;/span&gt;
              &lt;span style="color: #cd0000;"&gt;:nbands&lt;/span&gt; 6
              &lt;span style="color: #cd0000;"&gt;:encut&lt;/span&gt; 350
              &lt;span style="color: #cd0000;"&gt;:atoms&lt;/span&gt; co)))
  (&lt;span style="color: #8b0000;"&gt;dolist&lt;/span&gt; (d '(1.05 1.1 1.15 1.2 1.25))
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;change working directory&lt;/span&gt;
    (setf (oref calc wd) (format &lt;span style="color: #228b22;"&gt;"co-%s"&lt;/span&gt; d))
    ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;set x-coordinate on oxygen atom&lt;/span&gt;
    (setf (oref (elt (oref co atoms) 1) x) d)
    (print (format &lt;span style="color: #228b22;"&gt;"d = %s\nEnergy = %s eV"&lt;/span&gt;
                   d
                   (get-potential-energy calc)))))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
"d = 1.05
Energy = -14.195892 eV"

"d = 1.1
Energy = -14.698456 eV"

"d = 1.15
Energy = -14.814809 eV"

"d = 1.2
Energy = -14.660395 eV"

"d = 1.25
Energy = -14.319904 eV"
&lt;/pre&gt;

&lt;p&gt;
See &lt;a href="http://kitchingroup.cheme.cmu.edu/dft-book/dft.html#sec-3-4-1"&gt;http://kitchingroup.cheme.cmu.edu/dft-book/dft.html#sec-3-4-1&lt;/a&gt; for how this was done in Python. It looks pretty similar to me.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="outline-container-sec-5" class="outline-2"&gt;
&lt;h2 id="sec-5"&gt;&lt;span class="section-number-2"&gt;5&lt;/span&gt; Summary thoughts&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-5"&gt;
&lt;p&gt;
We implemented a bare bones emacs-lisp calculator for VASP. The library automates creation of input files, running the calculation, and parsing the output.
&lt;/p&gt;

&lt;p&gt;
It seems pretty feasible to implement a pretty complete interface to VASP in emacs-lisp. The main reasons to do this are:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;Integrated access to documentation
&lt;/li&gt;
&lt;li&gt;Emacs editing of emacs-lisp code 
&lt;/li&gt;
&lt;li&gt;Integration with org-mode
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Even with Python editor that had access to documentation as deeply integrated as emacs has with emacs-lisp, it would still just be a Python editor, i.e. you probably could not use the editor to write org-mode, LaTeX, etc&amp;#x2026; It is time to recognize we need both scientific document creation &lt;i&gt;and&lt;/i&gt; code editing capability in the same place! This kind of suggests a need to get a better Python environment going in Emacs, which deeper integration of the documentation. See &lt;a href="http://kitchingroup.cheme.cmu.edu/blog/2014/12/20/A-new-mode-for-Python-documentation/"&gt;this&lt;/a&gt; post for some progress in that area!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Copyright (C) 2014 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2014/12/24/A-prototype-implementation-of-jasp-in-emacs-lisp.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;&lt;p&gt;Org-mode version = 8.2.10&lt;/p&gt;]]></content:encoded>
    </item>
    <item>
      <title>The sqlite variation of ase.db</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2014/04/17/The-sqlite-variation-of-ase-db</link>
      <pubDate>Thu, 17 Apr 2014 15:51:20 EDT</pubDate>
      <category><![CDATA[ase]]></category>
      <category><![CDATA[vasp]]></category>
      <guid isPermaLink="false">pR_wrfjI3Fu-fxOI6UnpBeZDCcI=</guid>
      <description>The sqlite variation of ase.db</description>
      <content:encoded><![CDATA[


&lt;div id="table-of-contents"&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;div id="text-table-of-contents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#sec-1"&gt;1. Exploring the database with sqlite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-2"&gt;2. The python interface to the ase-db&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-3"&gt;3. Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
In a recent &lt;a href="http://kitchingroup.cheme.cmu.edu/blog/2014/03/26/writing-VASP-calculations-to-ase-db-formats/"&gt;post&lt;/a&gt; we explored writing VASP calculations to an ase database in json format. Today we explore a similar idea, but writing to sqlite. I have incorporated the code from the previous post into a utils module in jasp.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp.utils &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; get_jasp_dirs(&lt;span style="color: #228b22;"&gt;'/home-research/jkitchin/research/rutile-atat'&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
['/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/0', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/1', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/10', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/11', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/12', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/13', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/14', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/15', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/16', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/17', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/2', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/3', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/4', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/5', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/59', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/6', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/66', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/7', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/73', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/74', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/78', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/8', '/home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/9']
&lt;/pre&gt;

&lt;p&gt;
That new function &lt;code&gt;get_jasp_dirs&lt;/code&gt; just returns a list of directories that are known finished VASP calculations. We will use a functional style of programming to map a function onto each directory in that list.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp.utils &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *

&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase.db &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; connect

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;I want a sqlite extension, so we have to specify db as the type, which means sqlite&lt;/span&gt;
&lt;span style="color: #8b008b;"&gt;c&lt;/span&gt; = connect(&lt;span style="color: #228b22;"&gt;'vaspdb.sqlite'&lt;/span&gt;, &lt;span style="color: #cd0000;"&gt;type&lt;/span&gt;=&lt;span style="color: #228b22;"&gt;'db'&lt;/span&gt;)

&lt;span style="color: #8b008b;"&gt;dirs&lt;/span&gt; = get_jasp_dirs(&lt;span style="color: #228b22;"&gt;'/home-research/jkitchin/research/rutile-atat'&lt;/span&gt;)

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;write&lt;/span&gt;(directory):
    &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; jasp(directory) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; calc:
        &lt;span style="color: #8b008b;"&gt;atoms&lt;/span&gt; = calc.get_atoms()
        &lt;span style="color: #8b008b;"&gt;calc.results&lt;/span&gt;[&lt;span style="color: #228b22;"&gt;'energy'&lt;/span&gt;] = atoms.get_potential_energy()
        &lt;span style="color: #8b008b;"&gt;calc.results&lt;/span&gt;[&lt;span style="color: #228b22;"&gt;'forces'&lt;/span&gt;] = atoms.get_forces()
    &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; c.write(atoms), directory

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;functional approach to writing&lt;/span&gt;
&lt;span style="color: #cd0000;"&gt;map&lt;/span&gt;(write, dirs)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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
&lt;/pre&gt;

&lt;p&gt;
Now, we have a sqlite database. Let us explore that a bit before using the python interface again. 
&lt;/p&gt;

&lt;div id="outline-container-sec-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;&lt;span class="section-number-2"&gt;1&lt;/span&gt; Exploring the database with sqlite&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-1"&gt;
&lt;p&gt;
First we see the tables.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sqlite"&gt;.tables
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
keywords           species            text_key_values  
number_key_values  systems          
&lt;/pre&gt;

&lt;p&gt;
We can see details of the tables like this.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sqlite"&gt;select * from sqlite_master;
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
table|systems|systems|2|CREATE TABLE systems (
    id integer primary key autoincrement,
    unique_id text unique,
    ctime real,
    mtime real,
    user text,
    numbers blob,
    positions blob,
    cell blob,
    pbc integer,
    initial_magmoms blob,
    initial_charges blob,
    masses blob,
    tags blob,
    momenta blob,
    constraints text,
    calculator text,
    calculator_parameters text,
    energy real,
    free_energy real,
    forces blob,
    stress blob,
    dipole blob,
    magmoms blob,
    magmom blob,
    charges blob,
    data text)
index|sqlite_autoindex_systems_1|systems|3|
table|sqlite_sequence|sqlite_sequence|4|CREATE TABLE sqlite_sequence(name,seq)
table|species|species|5|CREATE TABLE species (
    Z integer,
    n integer,
    id text,
    foreign key (id) references systems(id))
table|keywords|keywords|6|CREATE TABLE keywords (
    keyword text,
    id text,
    foreign key (id) references systems(id))
table|text_key_values|text_key_values|8|CREATE TABLE text_key_values (
    key text,
    value text,
    id text,
    foreign key (id) references systems(id))
table|number_key_values|number_key_values|10|CREATE TABLE number_key_values (
    key text,
    value real,
    id text,
    foreign key (id) references systems (id))
index|unique_id_index|systems|11|CREATE INDEX unique_id_index on systems(unique_id)
index|ctime_index|systems|12|CREATE INDEX ctime_index on systems(ctime)
index|user_index|systems|13|CREATE INDEX user_index on systems(user)
index|calculator_index|systems|14|CREATE INDEX calculator_index on systems(calculator)
index|species_index|species|15|CREATE INDEX species_index on species(Z)
index|keyword_index|keywords|16|CREATE INDEX keyword_index on keywords(keyword)
index|text_index|text_key_values|17|CREATE INDEX text_index on text_key_values(key)
index|number_index|number_key_values|18|CREATE INDEX number_index on number_key_values(key)
&lt;/pre&gt;

&lt;p&gt;
Let us see one entry from the systems table.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sqlite"&gt;select * from systems where id=1;
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
id|unique_id|ctime|mtime|user|numbers|positions|cell|pbc|initial_magmoms|initial_charges|masses|tags|momenta|constraints|calculator|calculator_parameters|energy|free_energy|forces|stress|dipole|magmoms|magmom|charges|data
1|3ed58bb16897177be0ed56400c90b6f4|14.2361260035084|14.2361260035084|jkitchin|@|7|||||||vasp|{"incar": {"doc": "INCAR parameters", "nbands": 43, "sigma": 0.1, "prec": "high", "encut": 350.0}, "doc": "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", "potcar": [["Ru", "potpaw_PBE/Ru/POTCAR", "dee616f2a1e7a5430bb588f1710bfea3001d54ea"], ["O", "potpaw_PBE/O/POTCAR", "9a0489b46120b0cad515d935f44b5fbe3a3b1dfa"]], "input": {"kpts": [6, 6, 10], "kpts_nintersections": null, "reciprocal": false, "setups": {}, "xc": "PBE", "txt": "-", "gamma": true}, "atoms": {"cell": [[4.526933343669885, 0.0, 0.0], [0.0, 4.526933343669885, 0.0], [0.0, 0.0, 3.095292162609941]], "symbols": ["O", "O", "O", "O", "Ru", "Ru"], "tags": [0, 0, 0, 0, 0, 0], "pbc": [true, true, true], "positions": [[1.3820537023391204, 1.3820537023391204, 0.0], [3.1448796413307645, 3.1448796413307645, 0.0], [3.645520374174063, 0.8814129694958222, 1.5476460813049704], [0.8814129694958222, 3.645520374174063, 1.5476460813049704], [0.0, 0.0, 0.0], [2.2634666718349425, 2.2634666718349425, 1.5476460813049704]]}, "data": {"stress": [0.0884313161515024, 0.0884313161515024, 0.06042693164307849, -0.0, -0.0, -0.0], "doc": "Data from the output of the calculation", "volume": 63.432210741434858, "total_energy": -44.251496, "forces": [[-0.023609, -0.023609, 0.0], [0.023609, 0.023609, 0.0], [-0.023609, 0.023609, 0.0], [0.023609, -0.023609, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], "fermi_level": 5.0374}, "metadata": {"date.created": 1395241327.477995, "uuid": "7081ee4a-af77-11e3-a6e6-003048f5e49e", "date.created.ascii": "Wed Mar 19 11:02:07 2014", "user.username": "jkitchin", "atoms.resort": [2, 3, 4, 5, 0, 1], "user.email": "jkitchin@andrew.cmu.edu", "user.fullname": "John Kitchin", "O.potential.git_hash": "9a0489b46120b0cad515d935f44b5fbe3a3b1dfa", "atoms.tags": [0, 0, 0, 0, 0, 0], "O.potential.path": "potpaw_PBE/O/POTCAR", "Ru.potential.path": "potpaw_PBE/Ru/POTCAR", "Ru.potential.git_hash": "dee616f2a1e7a5430bb588f1710bfea3001d54ea"}}|-44.251496||+|||||{"keywords": [], "data": {}, "key_value_pairs": {}}
&lt;/pre&gt;

&lt;p&gt;
How about the species table:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sqlite"&gt;select * from species where id=1;
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Z|n|id
8|4|1
44|2|1
&lt;/pre&gt;

&lt;p&gt;
Now we can find a calculation with two Ru and 4 oxygen atoms, but it takes some sqlite knowledge.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sqlite"&gt;select sp1.id,sys.id 
from species as sp1 
inner join
species as sp2
on sp1.id = sp2.id
inner join systems as sys
on sp1.id=sys.id
where (sp1.Z=44 and sp1.n=2) and (sp2.Z=8 and sp2.n=4);
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
id|id
1|1
&lt;/pre&gt;

&lt;p&gt;
That is an expected result. Let us get back to the python interface.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-2" class="outline-2"&gt;
&lt;h2 id="sec-2"&gt;&lt;span class="section-number-2"&gt;2&lt;/span&gt; The python interface to the ase-db&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-2"&gt;
&lt;p&gt;
Let us search for entries containing 2 Ru atoms and 4 O atoms again. We know this should be the first entry from before. Note how much simpler this syntax is.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase.db &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; connect

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;I want a sqlite extension, so we have to specify db as the type, which means sqlite&lt;/span&gt;
&lt;span style="color: #8b008b;"&gt;c&lt;/span&gt; = connect(&lt;span style="color: #228b22;"&gt;'vaspdb.sqlite'&lt;/span&gt;, &lt;span style="color: #cd0000;"&gt;type&lt;/span&gt;=&lt;span style="color: #228b22;"&gt;'db'&lt;/span&gt;)

&lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; row &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; c.select(&lt;span style="color: #228b22;"&gt;'Ru=2,O=4'&lt;/span&gt;): &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; row
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
{'ctime': 14.236126003508412, 'energy': -44.251496, 'tags': array([0, 0, 0, 0, 0, 0], dtype=int32), 'positions': array([[ 1.3820537 ,  1.3820537 ,  0.        ],
       [ 3.14487964,  3.14487964,  0.        ],
       [ 3.64552037,  0.88141297,  1.54764608],
       [ 0.88141297,  3.64552037,  1.54764608],
       [ 0.        ,  0.        ,  0.        ],
       [ 2.26346667,  2.26346667,  1.54764608]]), 'calculator': u'vasp', '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.52693334,  0.        ,  0.        ],
       [ 0.        ,  4.52693334,  0.        ],
       [ 0.        ,  0.        ,  3.09529216]]), 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.3820537 ,  1.3820537 ,  0.        ],
       [ 3.14487964,  3.14487964,  0.        ],
       [ 3.64552037,  0.88141297,  1.54764608],
       [ 0.88141297,  3.64552037,  1.54764608],
       [ 0.        ,  0.        ,  0.        ],
       [ 2.26346667,  2.26346667,  1.54764608]])}, u'data': {u'stress': array([ 0.08843132,  0.08843132,  0.06042693, -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.023609, -0.023609,  0.      ],
       [ 0.023609,  0.023609,  0.      ],
       [-0.023609,  0.023609,  0.      ],
       [ 0.023609, -0.023609,  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'}}, 'cell': array([[ 4.52693334,  0.        ,  0.        ],
       [ 0.        ,  4.52693334,  0.        ],
       [ 0.        ,  0.        ,  3.09529216]]), 'numbers': array([ 8,  8,  8,  8, 44, 44], dtype=int32), 'forces': array([[-0.023609, -0.023609,  0.      ],
       [ 0.023609,  0.023609,  0.      ],
       [-0.023609,  0.023609,  0.      ],
       [ 0.023609, -0.023609,  0.      ],
       [ 0.      ,  0.      ,  0.      ],
       [ 0.      ,  0.      ,  0.      ]]), 'mtime': 14.236126003508412, 'pbc': array([ True,  True,  True], dtype=bool), 'id': 1, 'unique_id': u'3ed58bb16897177be0ed56400c90b6f4', 'user': u'jkitchin'}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-3" class="outline-2"&gt;
&lt;h2 id="sec-3"&gt;&lt;span class="section-number-2"&gt;3&lt;/span&gt; Summary&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-3"&gt;
&lt;p&gt;
It is not yet obvious what the advantage of the sqlite format over the json format is. One is that you can use SQL to create queries, which is probably more powerful than the ase-db format. It is a little mysterious how the ase-db searches the json format to me.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Copyright (C) 2014 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2014/04/17/The-sqlite-variation-of-ase.db.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;&lt;p&gt;Org-mode version = 8.2.5h&lt;/p&gt;
]]></content:encoded>
    </item>
    <item>
      <title>writing VASP calculations to ase.db formats</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2014/03/26/writing-VASP-calculations-to-ase-db-formats</link>
      <pubDate>Wed, 26 Mar 2014 13:22:12 EDT</pubDate>
      <category><![CDATA[ase]]></category>
      <category><![CDATA[vasp]]></category>
      <guid isPermaLink="false">JvzDonDHKGTXceUksn5kMrUkczI=</guid>
      <description>writing VASP calculations to ase.db formats</description>
      <content:encoded><![CDATA[


&lt;div id="table-of-contents"&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;div id="text-table-of-contents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#sec-1"&gt;1. The command-line interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-2"&gt;2. Summary thoughts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
The ase development team has created a new database module (&lt;a href="https://wiki.fysik.dtu.dk/ase/ase/db/db.html"&gt;https://wiki.fysik.dtu.dk/ase/ase/db/db.html&lt;/a&gt; ). In this post, we will examine how to use that in conjunction with &lt;code&gt;jasp&lt;/code&gt; to save calculations to a database. To use this you need the latest version of jasp from &lt;a href="http://github.com/jkitchin/jasp"&gt;http://github.com/jkitchin/jasp&lt;/a&gt; .
&lt;/p&gt;

&lt;p&gt;
The idea here is to use the code from &lt;a href="http://kitchingroup.cheme.cmu.edu/blog/2014/03/20/Finding-VASP-calculations-in-a-directory-tree/"&gt;http://kitchingroup.cheme.cmu.edu/blog/2014/03/20/Finding-VASP-calculations-in-a-directory-tree/&lt;/a&gt; to add each calculation in that subtree to an ase database. We will use the json format for the database.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; os
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase.db &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; connect
&lt;span style="color: #8b008b;"&gt;c&lt;/span&gt; = connect(&lt;span style="color: #228b22;"&gt;'vaspdb.json'&lt;/span&gt;)

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;vasp_p&lt;/span&gt;(directory):
    &lt;span style="color: #228b22;"&gt;'returns True if a finished OUTCAR file exists in the current directory, else False'&lt;/span&gt;
    &lt;span style="color: #8b008b;"&gt;outcar&lt;/span&gt; = os.path.join(directory, &lt;span style="color: #228b22;"&gt;'OUTCAR'&lt;/span&gt;)
    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; os.path.exists(outcar):
        &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;open&lt;/span&gt;(outcar, &lt;span style="color: #228b22;"&gt;'r'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
            &lt;span style="color: #8b008b;"&gt;contents&lt;/span&gt; = f.read()
            &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'General timing and accounting informations for this job:'&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; contents:
                &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;True&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;False&lt;/span&gt;
            
        
&lt;span style="color: #8b008b;"&gt;total_time&lt;/span&gt; = 0

&lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; root, dirs, files &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; os.walk(&lt;span style="color: #228b22;"&gt;'/home-research/jkitchin/research/rutile-atat'&lt;/span&gt;):
    &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; d &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; dirs:
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;compute absolute path to each directory in the current root&lt;/span&gt;
        &lt;span style="color: #8b008b;"&gt;absd&lt;/span&gt; = os.path.join(root, d)
        &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; vasp_p(absd):
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;we found a vasp directory, so we can do something in it. &lt;/span&gt;
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;here we get the elapsed time from the calculation&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; jasp(absd) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; calc:
                &lt;span style="color: #8b008b;"&gt;atoms&lt;/span&gt; = calc.get_atoms()
                &lt;span style="color: #8b008b;"&gt;calc.results&lt;/span&gt;[&lt;span style="color: #228b22;"&gt;'energy'&lt;/span&gt;] = atoms.get_potential_energy()
                &lt;span style="color: #8b008b;"&gt;calc.results&lt;/span&gt;[&lt;span style="color: #228b22;"&gt;'forces'&lt;/span&gt;] = atoms.get_forces()
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;it is important that this line not be inside the jasp&lt;/span&gt;
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;context-manager, because c.write writes in the local&lt;/span&gt;
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;dir.&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; c.write(atoms, [&lt;span style="color: #228b22;"&gt;'atat'&lt;/span&gt;]), absd
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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
&lt;/pre&gt;

&lt;p&gt;
The result is in this file: &lt;a href="/media/2014-03-26-writing-VASP-calculations-to-ase.db-formats/vaspdb.json"&gt;vaspdb.json&lt;/a&gt; .
&lt;/p&gt;

&lt;p&gt;
We can see the contents of that database like this:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; os
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase.db &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; connect
&lt;span style="color: #8b008b;"&gt;c&lt;/span&gt; = connect(&lt;span style="color: #228b22;"&gt;'vaspdb.json'&lt;/span&gt;)

&lt;span style="color: #8b008b;"&gt;g&lt;/span&gt; = c.select()  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;g is a generator&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; g.&lt;span style="color: #cd0000;"&gt;next&lt;/span&gt;()
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
{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'}
&lt;/pre&gt;

&lt;p&gt;
The data stored there comes from the calc.todict() function written for jasp.
&lt;/p&gt;

&lt;p&gt;
We can do some searches like this. Say we want to find all the calculations where there are four oxygen atoms.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; os
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase.db &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; connect
&lt;span style="color: #8b008b;"&gt;c&lt;/span&gt; = connect(&lt;span style="color: #228b22;"&gt;'vaspdb.json'&lt;/span&gt;)

&lt;span style="color: #8b008b;"&gt;g&lt;/span&gt; = c.select(O=4)  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;g is a generator&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; entry &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; g:
    &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; c.get_atoms(entry[&lt;span style="color: #228b22;"&gt;'id'&lt;/span&gt;]), &lt;span style="color: #228b22;"&gt;'\n'&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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(...))
&lt;/pre&gt;

&lt;p&gt;
You can see there are three calculations with that criterion.
&lt;/p&gt;

&lt;div id="outline-container-sec-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;&lt;span class="section-number-2"&gt;1&lt;/span&gt; The command-line interface&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-1"&gt;
&lt;p&gt;
There is also a command-line interface.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;ase-db --help
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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
&lt;/pre&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
Below are some examples that do work. We can list details of the calculation with id=1.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;ase-db vaspdb.json &lt;span style="color: #8b008b;"&gt;id&lt;/span&gt;=1
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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
&lt;/pre&gt;

&lt;p&gt;
Get calculations with four oxygen atoms:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;ase-db vaspdb.json &lt;span style="color: #8b008b;"&gt;O&lt;/span&gt;=4
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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
&lt;/pre&gt;

&lt;p&gt;
Get all calculations tagged with atat
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;ase-db vaspdb.json atat
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
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
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-2" class="outline-2"&gt;
&lt;h2 id="sec-2"&gt;&lt;span class="section-number-2"&gt;2&lt;/span&gt; Summary thoughts&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-2"&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Copyright (C) 2014 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2014/03/26/writing-VASP-calculations-to-ase.db-formats.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;&lt;p&gt;Org-mode version = 8.2.5h&lt;/p&gt;]]></content:encoded>
    </item>
    <item>
      <title>Finding VASP calculations in a directory tree</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2014/03/20/Finding-VASP-calculations-in-a-directory-tree</link>
      <pubDate>Thu, 20 Mar 2014 20:09:26 EDT</pubDate>
      <category><![CDATA[vasp]]></category>
      <category><![CDATA[python]]></category>
      <guid isPermaLink="false">dJVXTxeMC7XkaZ7TwVitwNM_m0Q=</guid>
      <description>Finding VASP calculations in a directory tree</description>
      <content:encoded><![CDATA[



&lt;p&gt;
The goal in this post is to work out a way to find all the directories in some root directory that contain VASP calculations. This is a precursor to doing something with those directories, e.g. creating a summary file, adding entries to a database, doing some analysis, etc&amp;#x2026; For fun, we will just calculate the total elapsed time in the calculations.
&lt;/p&gt;

&lt;p&gt;
What is challenging about this problem is that the calculations are often nested in a variety of different subdirectories, and we do not always know the structure. We need to recursively descend into those directories to check if they contain VASP calculations. 
&lt;/p&gt;

&lt;p&gt;
We will use a function that returns True or False to tell us if a particular directory is a VASP calculation or not. We can tell that because a completed VASP calculation has specific files in it, and specific content in those files. Notably, there is an OUTCAR file that contains the text "General timing and accounting informations for this job:" near the end of the file.
&lt;/p&gt;

&lt;p&gt;
We will also use &lt;a href="http://docs.python.org/2/library/os.html#os.walk"&gt;os.walk&lt;/a&gt; as the way to recursively descend into the root directory.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; os
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;vasp_p&lt;/span&gt;(directory):
    &lt;span style="color: #228b22;"&gt;'returns True if a finished OUTCAR file exists in the current directory, else False'&lt;/span&gt;
    &lt;span style="color: #8b008b;"&gt;outcar&lt;/span&gt; = os.path.join(directory, &lt;span style="color: #228b22;"&gt;'OUTCAR'&lt;/span&gt;)
    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; os.path.exists(outcar):
        &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;open&lt;/span&gt;(outcar, &lt;span style="color: #228b22;"&gt;'r'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
            &lt;span style="color: #8b008b;"&gt;contents&lt;/span&gt; = f.read()
            &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'General timing and accounting informations for this job:'&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; contents:
                &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;True&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;False&lt;/span&gt;
            
        
&lt;span style="color: #8b008b;"&gt;total_time&lt;/span&gt; = 0

&lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; root, dirs, files &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; os.walk(&lt;span style="color: #228b22;"&gt;'/home-research/jkitchin/research/rutile-atat'&lt;/span&gt;):
    &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; d &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; dirs:
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;compute absolute path to each directory in the current root&lt;/span&gt;
        &lt;span style="color: #8b008b;"&gt;absd&lt;/span&gt; = os.path.join(root, d)
        &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; vasp_p(absd):
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;we found a vasp directory, so we can do something in it. &lt;/span&gt;
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;here we get the elapsed time from the calculation&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; jasp(absd) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; calc:
                &lt;span style="color: #8b008b;"&gt;total_time&lt;/span&gt; += calc.get_elapsed_time()

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'Total computational time on this project is {0:1.0f} minutes.'&lt;/span&gt;.&lt;span style="color: #cd0000;"&gt;format&lt;/span&gt;(total_time / 60)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Total computational time on this project is 231 minutes.
&lt;/pre&gt;
&lt;p&gt;Copyright (C) 2014 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2014/03/20/Finding-VASP-calculations-in-a-directory-tree.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;&lt;p&gt;Org-mode version = 8.2.5h&lt;/p&gt;]]></content:encoded>
    </item>
    <item>
      <title>Serializing jasp calculations as json data</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/10/19/Serializing-jasp-calculations-as-json-data</link>
      <pubDate>Sat, 19 Oct 2013 14:33:51 EDT</pubDate>
      <category><![CDATA[jasp]]></category>
      <category><![CDATA[ase]]></category>
      <category><![CDATA[vasp]]></category>
      <guid isPermaLink="false">7Iyi5XdH1nYlzbMyfxMdYcLjqEg=</guid>
      <description>Serializing jasp calculations as json data</description>
      <content:encoded><![CDATA[


&lt;div id="table-of-contents"&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;div id="text-table-of-contents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#sec-1"&gt;1. The simplest case of a simple calculation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-2"&gt;2. Including extra information in the JSON file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sec-3"&gt;3. Limitations?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
We use &lt;a href="http://www.vasp.at/"&gt;VASP&lt;/a&gt;to calculate materials properties in our research We use the &lt;a href="https://github.com/jkitchin/jasp/tree/dev"&gt;jasp&lt;/a&gt;python module we have developed to setup, run and analyze those calculations. One of the things we have worked on developing recently is to more transparently share how do this kind of work by using org-mode supporting information files. Doing this should make our research more reproducible, and allow others to build off of it more easily.
&lt;/p&gt;

&lt;p&gt;
We have run into the following problem trying to share VASP results however. The VASP license prohibits us from sharing the POTCAR files that are used to run the calculations. That is unfortunate, but since these files are also what give VASP some competitive advantage, they are protected, and we agreed to that when we bought the license. The problem is that the &lt;code&gt;jasp&lt;/code&gt; module requires the POTCAR files to work, so without them, our scripts are not reproducible by researchers without a VASP license. 
&lt;/p&gt;

&lt;p&gt;
So, we have been looking at new ways to share the data from our calculations. In this post, we consider representing the calculation as a JSON file. We will look at a couple of new features built into the development branch of &lt;code&gt;jasp&lt;/code&gt;
&lt;/p&gt;

&lt;div id="outline-container-sec-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;&lt;span class="section-number-2"&gt;1&lt;/span&gt; The simplest case of a simple calculation&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-1"&gt;
&lt;p&gt;
Here we setup and run a simple calculation, and output the JSON file.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; Atoms, Atom
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
np.set_printoptions(precision=3, suppress=&lt;span style="color: #cd0000;"&gt;True&lt;/span&gt;)

&lt;span style="color: #8b008b;"&gt;co&lt;/span&gt; = Atoms([Atom(&lt;span style="color: #228b22;"&gt;'C'&lt;/span&gt;,[0,   0, 0]),
            Atom(&lt;span style="color: #228b22;"&gt;'O'&lt;/span&gt;,[1.2, 0, 0])],
            cell=(6., 6., 6.))

&lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; jasp(&lt;span style="color: #228b22;"&gt;'molecules/simple-co'&lt;/span&gt;, &lt;span style="color: #ff0000; font-weight: bold;"&gt;#&lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;output dir&lt;/span&gt;
          xc=&lt;span style="color: #228b22;"&gt;'PBE'&lt;/span&gt;,  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;the exchange-correlation functional&lt;/span&gt;
          nbands=6,  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;number of bands&lt;/span&gt;
          encut=350, &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;planewave cutoff&lt;/span&gt;
          ismear=1,  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;Methfessel-Paxton smearing&lt;/span&gt;
          sigma=0.01,&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;very small smearing factor for a molecule&lt;/span&gt;
          atoms=co) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; calc:
    &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'energy = {0} eV'&lt;/span&gt;.&lt;span style="color: #cd0000;"&gt;format&lt;/span&gt;(co.get_potential_energy())
    &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; co.get_forces()
    &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;open&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'JSON'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'w'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
        f.write(calc.json)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
energy = -14.687906 eV
[[ 5.095  0.     0.   ]
 [-5.095  0.     0.   ]]
&lt;/pre&gt;

&lt;p&gt;
Now, we can analyze the JSON file independently of jasp. The json data contains all the inputs we used for the VASP calculation, the atomic geometry, and many of the outputs of the calculation. Here is the &lt;a href="/media/2013-10-19-Serializing-jasp-calculations-as-json-data/JSON"&gt;JSON&lt;/a&gt;file.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; json
&lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;open&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'molecules/simple-co/JSON'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'rb'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
    &lt;span style="color: #8b008b;"&gt;d&lt;/span&gt; = json.loads(f.read())

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'The energy is {0}'&lt;/span&gt;.&lt;span style="color: #cd0000;"&gt;format&lt;/span&gt;(d[&lt;span style="color: #228b22;"&gt;'data'&lt;/span&gt;][&lt;span style="color: #228b22;"&gt;'total_energy'&lt;/span&gt;]))
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'The forces are {0}'&lt;/span&gt;.&lt;span style="color: #cd0000;"&gt;format&lt;/span&gt;(d[&lt;span style="color: #228b22;"&gt;'data'&lt;/span&gt;][&lt;span style="color: #228b22;"&gt;'forces'&lt;/span&gt;]))
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
The energy is -14.687906
The forces are [[5.095488, 0.0, 0.0], [-5.095488, 0.0, 0.0]]
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-2" class="outline-2"&gt;
&lt;h2 id="sec-2"&gt;&lt;span class="section-number-2"&gt;2&lt;/span&gt; Including extra information in the JSON file&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-2"&gt;
&lt;p&gt;
If we use a slightly different syntax, we can also include the total DOS in the JSON file.
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; jasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; *

&lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; jasp(&lt;span style="color: #228b22;"&gt;'molecules/simple-co'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; calc:
    &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;open&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'JSON-DOS'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'w'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
        f.write(calc_to_json(calc, dos=&lt;span style="color: #cd0000;"&gt;True&lt;/span&gt;))
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
To illustrate that we have done that, let us plot the DOS without using &lt;code&gt;jasp&lt;/code&gt; from the &lt;a href="/media/2013-10-19-Serializing-jasp-calculations-as-json-data/JSON-DOS"&gt;JSON-DOS&lt;/a&gt;file.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; json
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; plt

&lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;open&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'molecules/simple-co/JSON-DOS'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'rb'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
    &lt;span style="color: #8b008b;"&gt;d&lt;/span&gt; = json.loads(f.read())

&lt;span style="color: #8b008b;"&gt;energies&lt;/span&gt; = d[&lt;span style="color: #228b22;"&gt;'data'&lt;/span&gt;][&lt;span style="color: #228b22;"&gt;'dos'&lt;/span&gt;][&lt;span style="color: #228b22;"&gt;'e'&lt;/span&gt;]
&lt;span style="color: #8b008b;"&gt;dos&lt;/span&gt; = d[&lt;span style="color: #228b22;"&gt;'data'&lt;/span&gt;][&lt;span style="color: #228b22;"&gt;'dos'&lt;/span&gt;][&lt;span style="color: #228b22;"&gt;'dos'&lt;/span&gt;]
plt.plot(energies, dos)
plt.savefig(&lt;span style="color: #228b22;"&gt;'molecules/simple-co/dos.png'&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;img src="/media/2013-10-19-Serializing-jasp-calculations-as-json-data/dos.png"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
We are still working on getting atom-projected DOS into the json file, and ensuring that all the spin cases are handled (e.g. the spin-up and spin-down DOS).
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-sec-3" class="outline-2"&gt;
&lt;h2 id="sec-3"&gt;&lt;span class="section-number-2"&gt;3&lt;/span&gt; Limitations?&lt;/h2&gt;
&lt;div class="outline-text-2" id="text-3"&gt;
&lt;p&gt;
JSON is flexible, and can store text and numeric data. It does not store numpy arrays, but rather it is limited to storing lists of data. You would have to convert them back to arrays if you want to do array math. You probably wouldn't want to store a 3d array of electron density in this format, although it probably isn't worse than a CUBE file format. We haven't tested these files very significantly yet at a large scale to see how fast it is to read from lots of them.
&lt;/p&gt;

&lt;p&gt;
Nonetheless, this looks like a reasonable format to share data in human and machine readable form, without violating the VASP licence conditions.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Copyright (C) 2013 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2013/10/19/Serializing-jasp-calculations-as-json-data.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
    <item>
      <title>Subclassing an ase.calculators.vasp calculator to do post analysis</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/02/19/Subclassing-an-ase-calculators-vasp-calculator-to-do-post-analysis</link>
      <pubDate>Tue, 19 Feb 2013 09:00:00 EST</pubDate>
      <category><![CDATA[ase]]></category>
      <category><![CDATA[vasp]]></category>
      <guid isPermaLink="false">FQJPftD5NU9sF6oX-eYq654wl1E=</guid>
      <description>Subclassing an ase.calculators.vasp calculator to do post analysis</description>
      <content:encoded><![CDATA[



&lt;p&gt;
Recently someone &lt;a href="https://listserv.fysik.dtu.dk/pipermail/ase-users/2013-February/001683.html" &gt;reported&lt;/a&gt; on the ase-users mail list an issue they had with the Vasp calculator where the maximum number of electronic steps and then stops, even though the calculation is not converged. They asked how to make this raise an exception. This is not a built in feature in ase.calculators.vasp, but we can add it via a subclass. The idea is create a new class that inherits from ase.calculators.vasp, and then augment the calculate function to do some post analysis. In this case, we will parse the OUTCAR file looking for lines like:
&lt;/p&gt;

&lt;pre class="example"&gt;
----------------------------------------- Iteration    1(   1)  ---------------------------------------
&lt;/pre&gt;

&lt;p&gt;
I think the first integer corresponds to an ionic iteration, while the number in parentheses corresponds to an electronic iteration.  We will just count them up, and see if they match the values we specified. If they do, we can print an error message, or raise an exception. Here is the code:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase.calculators.vasp &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; Vasp
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; ase &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; Atom, Atoms
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; os, re

os.chdir(&lt;span style="color: #228b22;"&gt;'h2o-relax'&lt;/span&gt;)

&lt;span style="color: #8b0000;"&gt;class&lt;/span&gt; &lt;span style="color: #4682b4;"&gt;myvasp&lt;/span&gt;(Vasp):
    &lt;span style="color: #228b22;"&gt;'''subclass to run VASP and then check OUTCAR to see if the number&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    of electronic steps is equal to the max NELM specified, or if the&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    number of geometry steps is equal to NSW. Either case indicates&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    VASP may not be converged, but just stopped because it was told&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    too.'''&lt;/span&gt;

    &lt;span style="color: #ff0000; font-weight: bold;"&gt;#&lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;save original function&lt;/span&gt;
    
    &lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;calculate&lt;/span&gt;(&lt;span style="color: #8b0000;"&gt;self&lt;/span&gt;, *args):
        &lt;span style="color: #228b22;"&gt;'Run VASP, then check if nsw or nelm is met'&lt;/span&gt;

        &lt;span style="color: #ff0000; font-weight: bold;"&gt;#&lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;run original calculate method&lt;/span&gt;
        Vasp.calculate(&lt;span style="color: #8b0000;"&gt;self&lt;/span&gt;, *args)
        
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;now do post analysis&lt;/span&gt;
        NELM = &lt;span style="color: #8b0000;"&gt;self&lt;/span&gt;.int_params[&lt;span style="color: #228b22;"&gt;'nelm'&lt;/span&gt;]
        NSW = &lt;span style="color: #8b0000;"&gt;self&lt;/span&gt;.int_params[&lt;span style="color: #228b22;"&gt;'nsw'&lt;/span&gt;]

        max_nelm, max_nsw = 0, 0

        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;open OUTCAR and check for what you want&lt;/span&gt;
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;parse this line: - Iteration    1(   1)&lt;/span&gt;
        regexp = re.compile(&lt;span style="color: #228b22;"&gt;'Iteration\s+(?P&amp;lt;nsw&amp;gt;\d*)\(\s+(?P&amp;lt;nelm&amp;gt;\d*)\)'&lt;/span&gt;)
        count = 0
        &lt;span style="color: #8b0000;"&gt;with&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;open&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'OUTCAR'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; f:
            &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; line &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; f:
                &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'Iteration'&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; line:
                    m = regexp.search(line)
                    nsw = &lt;span style="color: #8b0000;"&gt;int&lt;/span&gt;(m.groupdict().get(&lt;span style="color: #228b22;"&gt;'nsw'&lt;/span&gt;))
                    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; nsw &amp;gt; max_nsw:
                        max_nsw = nsw
                    nelm = &lt;span style="color: #8b0000;"&gt;int&lt;/span&gt;(m.groupdict().get(&lt;span style="color: #228b22;"&gt;'nelm'&lt;/span&gt;))
                    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; nelm &amp;gt; max_nelm:
                        max_nelm = nelm

        &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; max_nelm == NELM:
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;raise exception here if you prefer&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; (&lt;span style="color: #228b22;"&gt;'{0} NELM steps taken! check convergence'&lt;/span&gt;.format(max_nelm))
        &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; max_nsw == NSW:
            &lt;span style="color: #8b0000;"&gt;print&lt;/span&gt;(&lt;span style="color: #228b22;"&gt;'{0} NSW steps taken! check convergence'&lt;/span&gt;.format(max_nsw))


atoms = Atoms([Atom(&lt;span style="color: #228b22;"&gt;'H'&lt;/span&gt;, [0.5960812, -0.7677068, 0.0000000]),
               Atom(&lt;span style="color: #228b22;"&gt;'O'&lt;/span&gt;, [0.0000000, 0.0000000, 0.0000000]),
               Atom(&lt;span style="color: #228b22;"&gt;'H'&lt;/span&gt;, [0.5960812, 0.7677068, 0.0000000])],
               cell=(8, 8, 8))

calc = myvasp(xc=&lt;span style="color: #228b22;"&gt;'PBE'&lt;/span&gt;,
              nelm=2,
              encut=400,
              ismear=0,&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;Gaussian smearing&lt;/span&gt;
              ibrion=2,
              ediff=1e-8,
              nsw=3)

atoms.set_calculator(calc)

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'Forces'&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'==========================='&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; atoms.get_forces()
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Forces
===========================
 running on    1 nodes
 distr:  one band on    1 nodes,    1 groups
 vasp.5.2.12 11Nov11 complex                                                    
  
 POSCAR found :  2 types and       3 ions
 LDA part: xc-table for Pade appr. of Perdew
 found WAVECAR, reading the header
 POSCAR, INCAR and KPOINTS ok, starting setup
 WARNING: small aliasing (wrap around) errors must be expected
 FFT: planning ...(           1 )
 reading WAVECAR
 the WAVECAR file was read sucessfully
 initial charge from wavefunction
 entering main loop
       N       E                     dE             d eps       ncg     rms          rms(c)
DAV:   1    -0.142298749169E+02   -0.14230E+02   -0.10298E-01    24   0.330E+00    0.231E-01
DAV:   2    -0.142281671566E+02    0.17078E-02   -0.36659E-03    24   0.581E-01
   1 F= -.14228167E+02 E0= -.14228167E+02  d E =-.142282E+02
 curvature:   0.00 expect dE= 0.000E+00 dE for cont linesearch  0.000E+00
 trial: gam= 0.00000 g(F)=  0.114E-04 g(S)=  0.000E+00 ort = 0.000E+00 (trialstep = 0.100E+01)
 search vector abs. value=  0.114E-04
 bond charge predicted
       N       E                     dE             d eps       ncg     rms          rms(c)
DAV:   1    -0.142273929196E+02    0.24820E-02   -0.17613E-03    24   0.419E-01    0.149E-02
DAV:   2    -0.142274190765E+02   -0.26157E-04   -0.20256E-04    16   0.115E-01
   2 F= -.14227419E+02 E0= -.14227419E+02  d E =0.748080E-03
 trial-energy change:    0.000748  1 .order   -0.000006   -0.000011   -0.000001
 step:   1.0700(harm=  1.0700)  dis= 0.00047  next Energy=   -14.228173 (dE=-0.609E-05)
 bond charge predicted
       N       E                     dE             d eps       ncg     rms          rms(c)
DAV:   1    -0.142274279955E+02   -0.35076E-04   -0.72088E-06    32   0.308E-02    0.758E-03
DAV:   2    -0.142274385490E+02   -0.10553E-04   -0.97783E-07    24   0.858E-03
   3 F= -.14227439E+02 E0= -.14227439E+02  d E =0.728608E-03
 curvature:  -0.53 expect dE=-0.133E-03 dE for cont linesearch -0.931E-08
 trial: gam=21.74088 g(F)=  0.248E-03 g(S)=  0.000E+00 ort = 0.445E-06 (trialstep = 0.204E-02)
 search vector abs. value=  0.565E-02
 writing wavefunctions
Running vanilla serial job
2 NELM steps taken! check convergence
3 NSW steps taken! check convergence
[[ 0.024 -0.028  0.   ]
 [-0.048  0.     0.   ]
 [ 0.024  0.028  0.   ]]
&lt;/pre&gt;
&lt;p&gt;Copyright (C) 2013 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2013/02/19/Subclassing-an-ase.calculators.vasp-calculator-to-do-post-analysis.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;
]]></content:encoded>
    </item>
  </channel>
</rss>
