Commit 07776415 authored by Marco Govoni's avatar Marco Govoni

Added data container. Bumped to 3.1.0.

parent beae7704
......@@ -16,3 +16,4 @@ Developers
- He Ma (University of Chicago)
- Han Yang (University of Chicago)
- Huihuo Zheng (Argonne National Laboratory)
......@@ -15,6 +15,9 @@ The software is tested for python version 3.x and has the following dependencies
- ``mendeleev``
- ``signac``
The dependencies will all be installed automatically, following instructions reported below.
Source Code Installation
========================
......
......@@ -53,3 +53,11 @@ Electronic Structure
:members:
:undoc-members:
:show-inheritance:
Data Container
--------------
.. automodule:: westpy.dataContainer
:members:
:undoc-members:
:show-inheritance:
......@@ -8,8 +8,8 @@ Overview
Features:
- Guided generation of input files for ground state density functional theory calculations (Qbox, QuantumEspresso)
- Guided generation of input filed for **WEST**
- Plot of DOS, LDOS, full-frequency self-energy
- *Guided generation of input filed for **WEST***
- Plot of DOS, *LDOS*, *full-frequency self-energy*
.. seealso::
**WEST** is massively parallel code for Many-Body Perturbation Theory calculations. Click `here <http://www.west-code.org/doc/West/latest/>`_ to know more.
......@@ -48,7 +48,7 @@
" |_| |___/ \n",
" \n",
"WEST version : 3.1.0\n",
"Today : 2018-06-25 18:12:53.140481\n"
"Today : 2018-06-29 15:23:25.768394\n"
]
}
],
......@@ -205,7 +205,7 @@
"/\n",
"&ELECTRONS\n",
"diago_full_acc = .TRUE.\n",
"conv_tol = 1.d-8\n",
"conv_thr = 1.d-8\n",
"/\n",
"ATOMIC_SPECIES\n",
"C 12.011 C_ONCV_PBE-1.0.upf\n",
......@@ -322,8 +322,8 @@
"output_type": "stream",
"text": [
"set cell 25.0 0.0 0.0 0.0 25.0 0.0 0.0 0.0 25.0\n",
"species Carbon C_ONCV_PBE-1.0.xml\n",
"species Hydrogen H_ONCV_PBE-1.0.xml\n",
"species Carbon http://www.quantum-simulation.org/potentials/sg15_oncv/xml/C_ONCV_PBE-1.0.xml\n",
"species Hydrogen http://www.quantum-simulation.org/potentials/sg15_oncv/xml/H_ONCV_PBE-1.0.xml\n",
"atom C1 Carbon 0.0 0.0 0.0\n",
"atom H2 Hydrogen 1.185992116575257 -1.185803143962673 1.185992116575257\n",
"atom H3 Hydrogen -1.185992116575257 1.185992116575257 1.185992116575257\n",
......
......@@ -48,7 +48,7 @@
" |_| |___/ \n",
" \n",
"WEST version : 3.1.0\n",
"Today : 2018-06-25 18:13:37.507463\n"
"Today : 2018-06-29 15:23:42.948747\n"
]
}
],
......@@ -186,8 +186,8 @@
"output_type": "stream",
"text": [
"set cell 25.0 0.0 0.0 0.0 25.0 0.0 0.0 0.0 25.0\n",
"species Carbon C_ONCV_PBE-1.0.xml\n",
"species Hydrogen C_ONCV_PBE-1.0.xml\n",
"species Carbon http://www.quantum-simulation.org/potentials/sg15_oncv/xml/C_ONCV_PBE-1.0.xml\n",
"species Hydrogen http://www.quantum-simulation.org/potentials/sg15_oncv/xml/C_ONCV_PBE-1.0.xml\n",
"atom C1 Carbon 0.0 0.0 0.0\n",
"atom H2 Hydrogen 1.185992116575257 -1.185803143962673 1.185992116575257\n",
"atom H3 Hydrogen -1.185992116575257 1.185992116575257 1.185992116575257\n",
......
......@@ -48,7 +48,7 @@
" |_| |___/ \n",
" \n",
"WEST version : 3.1.0\n",
"Today : 2018-06-25 18:10:14.838543\n"
"Today : 2018-06-29 15:24:08.077663\n"
]
}
],
......@@ -72,22 +72,6 @@
"es = ElectronicStructure()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We add information about the k-points, in this case only gamma."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"es.addKpoint(1,[0.,0.,0.])"
]
},
{
"cell_type": "markdown",
"metadata": {},
......@@ -97,7 +81,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -114,7 +98,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
......@@ -132,7 +116,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 5,
"metadata": {},
"outputs": [
{
......
......@@ -17,5 +17,5 @@ setup(name='westpy',
'mendeleev',
'signac'
],
python_requires='>=3.0, !=3.0.*, !=3.1.*, !=3.2.*, <4',
python_requires='>=2.7, >=3.0, !=3.0.*, !=3.1.*, !=3.2.*, <4',
zip_safe=True)
......@@ -5,6 +5,7 @@ from westpy.utils import *
from westpy.atom import *
from westpy.geometry import *
from westpy.groundState import *
from westpy.dataContainer import *
from westpy.electronicStructure import *
__version__ = '3.1.0'
......
from __future__ import print_function
class DataContainer() :
#
"""Class for representing an in-memory data container.
:Example:
>>> from westpy import *
>>> dc = DataContainer()
"""
#
def __init__(self) :
from signac import Collection
self.info = {}
self.coll = Collection()
#
def upsertPoint(self,identifier,document,incremental_update=True) :
"""Update or inserts an entry to the data container.
If identifier exists, update the document associated to the identifier, otherwise insert the document with the identifier.
:param identifier: identifier
:type key: * (hashable object)
:param document: document
:type document: * (hashable object)
:param incremental_update: if the document exists, only update it, do not remove its other keys.
:type incremental_update: boolean
:Example:
>>> from westpy import *
>>> dc = DataContainer()
>>> dc.upsertPoint({"a":1, "b":2},{"energy":-4.5})
"""
#
# check if identifier exists, if yes update its document, otherwise plain insert
#
point = self.coll.find_one({"i" : identifier})
if point is None :
self.coll.insert_one({"i" : identifier, "d" : document})
else :
if( incremental_update ) :
for key in document.keys() :
point["d"][key] = document[key]
self.coll.replace_one({"i" : identifier},point)
else :
self.coll.replace_one({"i" : identifier},{ "i" : identifier, "d" : document })
#
def showPoints(self) :
"""Shows all points of the data container.
:Example:
>>> from westpy import *
>>> dc = DataContainer()
>>> dc.upsertPoint({"a":1, "b":2},{"energy":-4.5})
>>> dc.showPoints()
"""
for point in self.coll :
print(point)
#
def removePoint(self,identifier) :
"""Removes point with given identifier from the data container.
:param identifier: identifier
:type key: * (hashable object)
:Example:
>>> from westpy import *
>>> dc = DataContainer()
>>> dc.upsertPoint({"a":1, "b":2},{"energy":-4.5})
>>> dc.removePoint({"a":1, "b":2})
"""
#
# check if identifier exists, if yes remove the point
#
self.coll.delete_one({"i" : identifier})
#
def upsertKey(self,key,description):
"""Updates or inserts a new key and its description.
:param key: key
:type key: string
:param description: description
:type description: * (hashable object)
:Example:
>>> from westpy import *
>>> dc = DataContainer()
>>> dc.upsertKey("a","the first letter")
"""
#
# if key exists update its description, otherwise insert
#
self.info[key] = description
#
def removeKey(self,key):
"""Removes the description of a key
:param key: key
:type key: string
:Example:
>>> from westpy import *
>>> dc = DataContainer()
>>> dc.upsertKey("a","the first letter")
>>> dc.removeKey("a")
"""
#
# if key exists, remove it
#
if key in self.info.keys() :
self.info.pop(key)
#
def checkKeys(self,printSummary=True):
"""Checks that all keys are described.
:param printSummary: if True prints summary
:type printSummary: boolean
:returns: True if all keys are described, False otherwise.
:rtype: boolean
:param key: key
:type key: string
:Example:
>>> from westpy import *
>>> dc = DataContainer()
>>> dc.upsertPoint({"a":1, "b":2},{"energy":-4.5})
>>> dc.upsertKey("a","the first letter")
>>> dc.upsertKey("b","another letter")
>>> dc.upsertKey("energy","a quantity")
>>> dc.checkKeys()
"""
#
undesc_keys = []
utilized_keys = []
unutilized_keys = []
#
for point in self.coll :
for key in point["i"].keys() :
if key not in utilized_keys :
utilized_keys.append(key)
if key not in self.info.keys() :
if key not in undesc_keys :
undesc_keys.append(key)
for key in point["d"].keys() :
if key not in utilized_keys :
utilized_keys.append(key)
if key not in self.info.keys() :
if key not in undesc_keys :
undesc_keys.append(key)
#
for key in self.info.keys() :
if key not in utilized_keys :
unutilized_keys.append(key)
# print summary
if( printSummary ) :
if( len(self.info.keys()) == 0 ) :
print( "Described keys : None")
for key in self.info.keys() :
print( "Described key ... ", key, " : ", self.info[key] )
if( len( undesc_keys ) > 0 ) :
print( "Undescribed keys ... ", undesc_keys )
if( len( unutilized_keys ) > 0 ) :
print( "Unutilized keys ... ", unutilized_keys )
#
return len(undesc_keys) == 0
from __future__ import print_function
class ElectronicStructure(object) :
class ElectronicStructure() :
"""Class for representing an electronic structure calculation.
:Example:
......@@ -11,51 +11,19 @@ class ElectronicStructure(object) :
"""
#
def __init__(self) :
self.info = {}
self.data = []
from westpy import DataContainer
self.dc = DataContainer()
self.dc.upsertKey("k","k-point")
self.dc.upsertKey("s","spin")
self.dc.upsertKey("b","band")
#
def loadFromJsonFile(self,fname) :
"""Loads an electronic structure from file (Json format).
:param fname: file name
:type fname: string
:Example:
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.loadFromJsonFile("es.json")
"""
from westpy import readJsonFile
data = readJsonFile(fname)
self.info = data["info"]
self.data = data["data"]
#
def dumpToJsonFile(self,fname) :
"""Dumps an electronic structure to file (Json format).
:param fname: file name
:type fname: string
:Example:
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.dumpToJsonFile("es.json")
"""
from westpy import writeJsonFile
data = {}
data["info"] = self.info
data["data"] = self.data
writeJsonFile(fname,data)
#
def addKey(self,key,value) :
"""Sets key-value in metadata.
def addKey(self,key,description) :
"""Describes metadata key.
:param key: key
:type key: string
:param value: value
:type value: string
:param description: description
:type description: * (hashable object)
:Example:
......@@ -63,9 +31,7 @@ class ElectronicStructure(object) :
>>> es = ElectronicStructure()
>>> es.addKey("eks","Kohn-Sham")
"""
if "keys" not in self.info.keys() :
self.info["keys"] = {}
self.info["keys"][key] = value
self.dc.upsertKey( key, description )
#
def removeKey(self,key) :
"""Removes key from metadata.
......@@ -77,15 +43,10 @@ class ElectronicStructure(object) :
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.addKey("eks","Kohn-Sham")
>>> es.removeKey("eks")
"""
if "keys" in self.info.keys() :
if key in self.info["keys"] :
self.info["keys"].pop(key,None)
else :
print("key not recognized")
else :
print("No keys")
self.dc.removeKey( key )
#
#
def showKeys(self) :
......@@ -96,110 +57,28 @@ class ElectronicStructure(object) :
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.showKeys()
"""
if "keys" in self.info.keys() :
for key in self.info["keys"] :
print( key, self.info["keys"][key])
else :
print("No keys")
#
def addKpoint(self,kpoint,coord) :
"""Adds kpoint info to metadata.
:param kpoint: k-point integer label
:type kpoint: int
:param coord: crystal coordinates of the k-point
:type coord: 3-dim list of int
:Example:
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.addKpoint(1,[0.,0.,0.])
"""
if "k" not in self.info.keys() :
self.info["k"] = {}
self.info["k"][kpoint] = [float(coord[0]), float(coord[1]), float(coord[2])]
"""
l = self.dc.checkKeys(printSummary=True)
#
def __addSpins(self,spins) :
"""Adds spin labels to metadata.
:param spin: list of spin integer label
:type spin: list of int
:Example:
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.addSpins([1,2])
"""
if "s" not in self.info.keys() :
self.info["s"] = []
for spin in spins :
self.info["s"].append(spin)
#
def __addBands(self,bands) :
"""Adds band label to metadata.
:param band: list of band integer label
:type band: list of int
:Example:
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.addBands([1,2,3])
"""
if "b" not in self.info.keys() :
self.info["b"] = []
for band in bands :
self.info["b"].append(band)
#
def addDataPoint(self,ksb,key,what) :
"""Adds datapoint to data.
:param ksb: triplet of k-point, spin, band (integer labels)
:param ksb: triplet of integers: k-point, spin, band (integer labels)
:type ksb: 3-dim int
:param key: key
:type key: string
:param what: content attached to key
:type what: *
:type what: * (hashable object)
:Example:
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.addKey("eks","Kohn-Sham energy in eV")
>>> es.addKpoint(1,[0.,0.,0.])
>>> es.addDataPoint([1,1,1],"eks",-4.6789)
"""
lk = False
lkey = False
if "k" in self.info.keys() :
lk = ( ksb[0] in self.info["k"] )
else :
print("No k")
if "keys" in self.info.keys() :
lkey = ( key in self.info["keys"] )
else :
print("No keys")
if( lk and lkey ) :
lfound = False
for x in self.data :
if x["ksb"] == ksb :
x[key] = what
lfound = True
break
if not lfound :
d = {}
d["ksb"] = ksb
d[key] = what
self.data.append(d)
else :
if not lk :
print(ksb[0], "not in k, add it first")
if not lkey :
print(key, "not in keys, add it first")
self.dc.upsertPoint( { "k" : ksb[0], "s" : ksb[1], "b" : ksb[2] }, { key : what } )
#
def plotDOS(self,k=1,s=1,energyKeys=["eks"],sigma=0.1,weight=1.,energyRange=[-20.,0.,0.01],fname="dos.png") :
......@@ -225,12 +104,11 @@ class ElectronicStructure(object) :
>>> from westpy import *
>>> es = ElectronicStructure()
>>> es.addKey("eks","Kohn-Sham energy in eV")
>>> es.addKpoint(1,[0.,0.,0.])
>>> es.addDataPoint([1,1,1],"eks",-4.6789)
>>> es.plotDOS(k=1,s=1,energyKeys=["eks"],energyRange=[-5.,-3,0.01])
"""
#
if(all(x in self.info["keys"] for x in energyKeys)) :
if(all(x in self.dc.info.keys() for x in energyKeys)) :
#
import numpy as np
import scipy as sp
......@@ -248,18 +126,18 @@ class ElectronicStructure(object) :
#
dosAxis[energyKey] = np.zeros ( (npte) )
#
for dataPoint in self.data :
for dataPoint in self.dc.coll :
#
if energyKey in dataPoint.keys() and dataPoint["ksb"][0] == k and dataPoint["ksb"][1] == s :
mu = dataPoint[energyKey]
if energyKey in dataPoint["d"].keys() and dataPoint["i"]["k"] == k and dataPoint["i"]["s"] == s :
mu = dataPoint["d"][energyKey]
emin.append( mu )
emax.append( mu )
if isinstance(sigma, str) :
si = dataPoint[sigma]
si = dataPoint["d"][sigma]
else :
si = sigma
if isinstance(weight, str) :
we = dataPoint[weight]
we = dataPoint["d"][weight]
else :
we = weight
#
......@@ -289,5 +167,5 @@ class ElectronicStructure(object) :
fig.clear()
else:
for energyKey in energyKeys :
if energyKey not in self.info["keys"] :
if energyKey not in self.dc.info.keys() :
print("Unrecognized energyKey:", energyKey)
from __future__ import print_function
class GroundState(object) :
class GroundState() :
"""Class for representing a ground state calculation with DFT.
:param geom: geometry (cell, atoms, species)
......@@ -145,7 +145,7 @@ class GroundState(object) :
#
file.write("&ELECTRONS\n")
file.write("diago_full_acc = .TRUE.\n")
file.write("conv_tol = 1.d-8\n")
file.write("conv_thr = 1.d-8\n")
file.write("/\n")
#
file.write("ATOMIC_SPECIES\n")
......@@ -203,7 +203,7 @@ class GroundState(object) :
for atom in self.geom.atoms :
if( atom.symbol not in sp ) :
sp.append(atom.symbol)
file.write("species " + self.geom.species[atom.symbol]["name"] + " " + self.geom.species[atom.symbol]["fname"] + "\n")
file.write("species " + self.geom.species[atom.symbol]["name"] + " " + self.geom.species[atom.symbol]["url"] + "\n")
# atom
i = 0
for atom in self.geom.atoms :
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment