#!/usr/bin/env python
# Copyright 2013 National Renewable Energy Laboratory, Golden CO, USA
# This file is part of NREL MatDB.
#
# NREL MatDB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# NREL MatDB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NREL MatDB. If not, see <http://www.gnu.org/licenses/>.
import datetime, hashlib, json, os, re, sys, traceback
import numpy as np
np.seterr( all='raise', under='ignore')
import psycopg2
import readVasp
import ScanDoscar
import wrapReceive
import wrapUpload
#====================================================================
vasprunName = 'vasprun.xml'
outcarName = 'OUTCAR'
#====================================================================
def badparms( msg):
'''
Prints an error msg and usage info, and exits with rc 1.
'''
print '\nError: %s' % (msg,)
print 'Parms:'
print ' -bugLev <int> Debug level'
print ' -func <string> createTableModel / fillTable'
print ' -useCommit <boolean> false/true: do we commit changes to the DB.'
print ' -requireIcsd <boolean> false/true: do we require that the file'
print ' paths names contain ICSD info.'
print ' -allowExc <boolean> false/true: continue after error.'
print ' -modType <string> SQL mod type: insert or update.'
print ' -readType <string> if outcar: OUTCAR; if xml: vasprun.xml'
print ' 2014-06-10: now we only support outcar,'
print ' since some info is not in vasprun.xml.'
print ' -deleteTable <boolean> false/true: If func is createTableModel,'
print ' do we delete the old table first.'
print ' -wrapPrefix <string> Prefix of dir names before wrapId,'
print ' like \'/data/arch/md.\''
print ' -topDir <string> Top of dir tree.'
print ' -dirList <string> File containing dirs to be ingested.'
print ' If a dir name ends with "metadata", the'
print ' "metadata" part is stripped.'
print ' -zzflag <string> Input file from wrapUpload.py.'
print ' -inSpec <string> JSON file containing DBMS parameters.'
sys.exit(1)
#====================================================================
[docs]def main():
'''
Reads a dir tree and adds rows to the database table "model".
The function is determined by the **-func** parameter; see below.
This function is called by wrapReceive.py.
Command line parameters:
================ ========= ==============================================
Parameter Type Description
================ ========= ==============================================
**-bugLev** integer Debug level. Normally 0.
**-func** string Function. See below.
**-useCommit** boolean false/true: do we commit changes to the DB.
**-requireIcsd** boolean no/yes: do we require that the file
path names contain ICSD info.
See notes below.
**-allowExc** boolean false/true: continue after error.
**-modType** string SQL mod type: insert or update.
**-readType** string if outcar: OUTCAR; if xml: for vasprun.xml.
2014-06-10: now we only support outcar,
since some info is not in vasprun.xml.
**-deleteTable** boolean false/true: If func is create*, do we
delete the old table first.
**-wrapPrefix** string Prefix of dir names before wrapId.
**-topDir** string Top of dir tree.
**-dirList** string File containing dirs to be ingested.
If a dir name ends with "metadata", the
"metadata" part is stripped.
**-zzflag** string Input file from wrapUpload.py.
**-inSpec** string JSON file containing DBMS parameters.
See below.
================ ========= ==============================================
**Values for the -func Parameter:**
**createTableModel**
Drop and create the model table. In this case the -topDir
and -dirList parameters should be "none".
**fillTable**
Read dirList and add rows to the database table "model".
**inSpec File Parameters:**
=================== ==============================================
Parameter Description
=================== ==============================================
**dbhost** Database hostname.
**dbport** Database port number.
**dbuser** Database user name.
**dbpswd** Database password.
**dbname** Database database name.
**dbschema** Database schema name.
**dbtablemodel** Database name of the "model" table.
=================== ==============================================
**inSpec file example:**::
{
"dbhost" : "scctest",
"dbport" : "6432",
"dbuser" : "x",
"dbpswd" : "x",
"dbname" : "cidlada",
"dbschema" : "satom",
"dbtablemodel" : "model"
}
**requireIcsd:**
If requireIcsd is true, :func:`getIcsdMap` must be able
to extract ICSD info from the file names. File names must be like: ::
.../icsd_083665/icsd_083665.cif/ls-anti-ferro-7/relax_cellshape/1
^^^^^^ ^^^^^^^^ ^ ^^^^^^^^^^^^^^^ ^
icsdNum magType magNum relaxType relaxNum
'''
bugLev = None
func = None
useCommit = None
requireIcsd = None
allowExc = None
modType = None
readType = None
deleteTable = None
wrapPrefix = None
topDir = None
dirList = None
zzflag = None
inSpec = None
if len(sys.argv) % 2 != 1:
badparms('Parms must be key/value pairs')
for iarg in range( 1, len(sys.argv), 2):
key = sys.argv[iarg]
val = sys.argv[iarg+1]
if key == '-bugLev': bugLev = int( val)
elif key == '-func': func = val
elif key == '-useCommit': useCommit = wrapUpload.parseBoolean( val)
elif key == '-requireIcsd': requireIcsd = wrapUpload.parseBoolean( val)
elif key == '-allowExc': allowExc = wrapUpload.parseBoolean( val)
elif key == '-modType': modType = val
elif key == '-readType': readType = val
elif key == '-deleteTable': deleteTable = wrapUpload.parseBoolean( val)
elif key == '-wrapPrefix': wrapPrefix = val
elif key == '-topDir': topDir = val
elif key == '-dirList': dirList = val
elif key == '-zzflag': zzflag = val
elif key == '-inSpec': inSpec = val
else: badparms('unknown key: "%s"' % (key,))
if bugLev == None: badparms('parm not specified: -bugLev')
if func == None: badparms('parm not specified: -func')
if useCommit == None: badparms('parm not specified: -useCommit')
if requireIcsd == None: badparms('missing parameter: -requireIcsd')
if allowExc == None: badparms('parm not specified: -allowExc')
if modType == None: badparms('parm not specified: -modType')
if modType not in ['insert', 'update']: badparms('invalid -modType')
if readType == None: badparms('parm not specified: -readType')
if deleteTable == None: badparms('parm not specified: -deleteTable')
if wrapPrefix == None: badparms('parm not specified: -wrapPrefix')
if topDir == None: badparms('parm not specified: -topDir')
if dirList == None: badparms('parm not specified: -dirList')
if zzflag == None: badparms('parm not specified: -zzflag')
if inSpec == None: badparms('parm not specified: -inSpec')
# 2014-06-10: now we only support outcar,
# since some info is not in vasprun.xml.
if readType != 'outcar': badparms('readType must be outcar')
fillDbVasp( bugLev, func, useCommit, requireIcsd, allowExc,
modType, readType, deleteTable, wrapPrefix, topDir, dirList,
zzflag, inSpec)
#====================================================================
[docs]def fillDbVasp(
bugLev,
func,
useCommit,
requireIcsd,
allowExc,
modType,
readType,
deleteTable,
wrapPrefix,
topDir,
dirList,
zzflag,
inSpec):
'''
Reads a dir tree and adds rows to the database table "model".
**Parameters**:
* bugLev (int): Debug level. Normally 0.
* func (str): Overall function. One of the following:
* ``'createTableModel'``
Drop and create the model table.
* ``'fillTable'``
Read a dir tree and add rows to the database table "model".
* useCommit (boolean): If True, we commit changes to the DB.
* requireIcsd (boolean): if True, the absTopDir string must
contain ICSD info that :func:`getIcsdMap` can extract.
* allowExc (boolean): If True, continue after error
* modType (string): SQL mod type: insert or update.
* readType (string): If outcar use OUTCAR; if xml use vasprun.xml.
* deleteTable (boolean): If True and func is create\*,
delete the specified table before creating it.
* wrapPrefix (str): Prefix of dir names before wrapId.
* topDir (str): Top of the directory tree.
* dirList (str): File containing dirs to be ingested.
If a dir name ends with "metadata", the
"metadata" part is stripped.
* zzflag (str): Input file from wrapUpload.py.
* inSpec (str): Name of JSON file containing DBMS parameters.
See description at :func:`main`.
**Returns**
* None
'''
if bugLev >= 1:
print 'fillDbVasp: func: %s' % (func,)
print 'fillDbVasp: useCommit: %s' % (useCommit,)
print 'fillDbVasp: requireIcsd: %s' % (requireIcsd,)
print 'fillDbVasp: allowExc: %s' % (allowExc,)
print 'fillDbVasp: modType: %s' % (modType,)
print 'fillDbVasp: readType: %s' % (readType,)
print 'fillDbVasp: deleteTable: %s' % (deleteTable,)
print 'fillDbVasp: topDir: %s' % (topDir,)
print 'fillDbVasp: dirList: %s' % (dirList,)
print 'fillDbVasp: zzflag: %s' % (zzflag,)
print 'fillDbVasp: inSpec: %s' % (inSpec,)
topDir = os.path.abspath( topDir)
if bugLev >= 1:
print 'fillDbVasp: abs topDir: %s' % (topDir,)
with open( inSpec) as fin:
specMap = json.load( fin)
dbhost = specMap.get('dbhost', None)
dbport = specMap.get('dbport', None)
dbuser = specMap.get('dbuser', None)
dbpswd = specMap.get('dbpswd', None)
dbname = specMap.get('dbname', None)
dbschema = specMap.get('dbschema', None)
dbtablemodel = specMap.get('dbtablemodel', None)
if dbhost == None: badparms('inSpec name not found: dbhost')
if dbport == None: badparms('inSpec name not found: dbport')
if dbuser == None: badparms('inSpec name not found: dbuser')
if dbpswd == None: badparms('inSpec name not found: dbpswd')
if dbname == None: badparms('inSpec name not found: dbname')
if dbschema == None: badparms('inSpec name not found: dbschema')
if dbtablemodel == None: badparms('inSpec name not found: dbtablemodel')
dbport = int( dbport)
if bugLev >= 1:
print 'fillDbVasp: dbhost: %s' % (dbhost,)
print 'fillDbVasp: dbport: %s' % (dbport,)
print 'fillDbVasp: dbuser: %s' % (dbuser,)
##np.set_printoptions( threshold=10000)
# Register psycopg2 adapter for np.ndarray
# The function formatArray is defined below.
def adaptVal( val):
msg = formatArray( val)
# AsIs provides getquoted() which just calls the wrapped object's str().
return psycopg2.extensions.AsIs( msg)
psycopg2.extensions.register_adapter( np.ndarray, adaptVal)
psycopg2.extensions.register_adapter( np.float, adaptVal)
psycopg2.extensions.register_adapter( np.float64, adaptVal)
psycopg2.extensions.register_adapter( np.int64, adaptVal)
psycopg2.extensions.register_adapter( np.string_, adaptVal)
# Validate the zzflag file
if zzflag != 'none':
with open( zzflag) as fin:
msg = fin.read()
msg = msg.strip()
toks = msg.split()
if len(toks) != 2 or toks[0] != wrapUpload.version:
throwerr('version mismatch')
conn = None
cursor = None
try:
conn = psycopg2.connect(
host=dbhost,
port=dbport,
user=dbuser,
password=dbpswd,
database=dbname)
cursor = conn.cursor()
cursor.execute('set search_path to %s', (dbschema,))
if func == 'createTableModel':
createTableModel( bugLev, useCommit, deleteTable,
conn, cursor, dbschema, dbtablemodel)
elif func == 'fillTable':
with open( dirList) as fin:
lines = fin.readlines()
for line in lines:
line = line.strip()
if len(line) > 0 and not line.startswith('#'):
curDir = line
# Strip trailing "/metadata", if any
if curDir.endswith('/'): curDir = curDir[:-1]
if curDir.endswith('metadata'): curDir = curDir[:-8]
if curDir.endswith('/'): curDir = curDir[:-1]
# Find wrapId
adir = os.path.abspath( curDir)
if not adir.startswith( wrapPrefix):
throwerr('invalid adir: %s' % (adir,))
wrapId = adir[ len(wrapPrefix) : ]
ix = wrapId.find('/')
if ix <= 0: throwerr('invalid wrapId: %s' % (wrapId,))
wrapId = wrapId[:ix]
fillRow( bugLev, useCommit, requireIcsd, allowExc, modType,
readType, wrapId, topDir, curDir, conn, cursor,
dbschema, dbtablemodel)
else: throwerr('unknown func: "%s"' % (func,))
finally:
if cursor != None: cursor.close()
if conn != None: conn.close()
#====================================================================
[docs]def createTableModel(
bugLev,
useCommit,
deleteTable,
conn,
cursor,
dbschema,
dbtablemodel):
'''
Creates the database table "model".
**Parameters**:
* bugLev (int): Debug level. Normally 0.
* useCommit (boolean): If True, we commit changes to the DB.
* deleteTable (boolean): If True, delete the table before creating it.
* conn (psycopg2.connection): Open DB connection
* cursor (psycopg2.cursor): Open DB cursor
* dbschema (str): Database schema name
* dbtablemodel (str): Database name of the "model" table.
**Returns**
* None
'''
if deleteTable:
cursor.execute('DROP TABLE IF EXISTS %s' % (dbtablemodel,))
if useCommit:
conn.commit()
cursor.execute('''
CREATE TABLE %s (
mident serial, -- unique ID for this row (this VASP run)
wrapid text, -- unique ID for the upload
abspath text, -- absolute path to dir
relpath text, -- relative path below topDir (tail of abspath)
-- Values derived from the directory path
-- by wrapUpload.py getIcsdMap.
-- Not stored in the database:
-- statMap: map of fileName -> statInfoMap for files in this dir.
icsdNum int, -- ICSD number in CIF file: _database_code_ICSD
magType text, -- type of magnetic moment:
-- hsf: hs-ferro. magNum = 0.
-- hsaf: hs-anti-ferro. magNum = test num.
-- lsf: ls-ferro. magNum = 0.
-- lsaf: ls-anti-ferro. magNum = test num.
-- nm: non-magnetic. magNum = 0.
magNum int, -- number of hs-anti-ferro or ls-anti-ferro test.
relaxType text, -- Type of run:
-- std: standard,
-- rc: relax_cellshape,
-- ri: relax_ions
relaxNum int, -- Folder num for rc or ri: 0, 1, ...
excMsg text, -- exception msg from readVasp.py
excTrace text, -- exception trace from readVasp.py
-- If excMsg != None,
-- all following fields are None.
-- Values set by readVasp.py
--- program, version, date etc ---
runDate timestamp, -- like '2013-03-11 10:07:01'
iterRealTimes double precision[], -- time (seconds) of each VASP iter
iterTotalTime double precision, -- sum of iterRealTimes
--- incar parameters ---
systemName text, -- mos2_024000.cif
encut_ev double precision, -- INCAR ENCUT value, eV
ibrion int, -- INCAR IBRION value
isif int, -- INCAR ISIF value
numSpin int, -- INCAR ISPIN
numKpoint int, -- NKPTS from OUTCAR or vasprun.xml
numBand int, -- NBANDS from OUTCAR or vasprun.xml
--- kpoints ---
--- general parameters ---
--- atom info ---
numAtom int, -- == sum( typeNums)
typeNames text[], -- unique atom types: ['Mo' 'S']
typeNums int[], -- num of each type: [2 4]
typeMasses_amu float[], -- mass of each type
typePseudos text[], -- pseudopotential name of each type
typeValences int[], -- valence of each type
atomNames text[], -- non-unique atom names:
-- ['Mo', 'Mo', 'S', 'S', 'S', 'S']
atomMasses_amu float[], -- non-unique atom masses
atomPseudos text[], -- non-unique pseodopotential names
atomValences int[], -- non-unique atom valences
--- initial structure ---
initialBasisMat double precision[][], -- one row per vector
initialRecipBasisMat double precision[][], -- one row per vector
initialCartPosMat double precision[][], -- one row per vector
initialFracPosMat double precision[][], -- one row per vector
--- final structure ---
finalBasisMat double precision[][], -- one row per vector
finalRecipBasisMat double precision[][], -- one row per vector
finalCartPosMat double precision[][], -- one row per vector
finalFracPosMat double precision[][], -- one row per vector
--- misc calculated values ---
numElectron int, -- total number of electrons
totalValence int, -- totalValence - numElectron = netCharge
netCharge int, -- totalvalence - numelectron
--- final volume and density ---
finalVolume_ang3 double precision, -- volume of cell, Angstrom3
finalDensity_g_cm3 double precision, -- final cell density, g/cm3
--- last calc forces ---
finalForceMat_ev_ang double precision[][], -- final force matrix, eV/angstrom
finalStressMat_kbar double precision[][], -- final stress matrix, kbar
finalPressure_kbar double precision, -- final pressure, kbar
--- eigenvalues and occupancies ---
eigenMat double precision[][], -- eigenvalue matrix
occupMat double precision[][], -- occupancy matrix
--- dielectric function ---
dielectricImag double precision[][], -- columns: E(ev),x,y,z,xy,yz,zx
dielectricReal double precision[][], -- columns: E(ev),x,y,z,xy,yz,zx
--- density of states
dosMat double precision[][], -- density of states matrix
--- energy, efermi0 ---
energyNoEntrp double precision, -- energy without entropy, eV
energyPerAtom double precision, -- energyNoEntrp / numAtom, eV
efermi0 double precision, -- energy(sigma->0), eV
-- Misc and LDAU --
scalefactor double precision, -- POSCAR scale factor
ismear double precision, -- ISMEAR from OUTCAR
sigma double precision, -- SIGMA from OUTCAR
ldautype int, -- LDAUTYPE from OUTCAR
ldaul_mat int[][], -- LDAU-L, numLdau * numType
ldauu_mat double precision[][], -- LDAU-U, numLdau * numType
ldauj_mat double precision[][], -- LDAU-J, numLdau * numType
ldauo_mat int[][], -- LDAU-O, numLdau * numType
--- cbMin, vbMax, bandgap, set by augmentDb.py ---
cbMin double precision, -- min conduction band energy, eV
vbMax double precision, -- max valence band energy, eV
bandgapdirect double precision, -- eV min direct bandgap
bandgapindirect double precision, -- eV min direct or
-- indirect bandgap
-- More values set by augmentDb.py
formula text, -- like 'Na3 Fe5 O9'
sortedformula text, -- sorted by elements, like 'Fe5 Na3 O9'
chemtext text, -- every token surrounded by spaces,
-- like ' Fe 5 Na 3 O 9 '
minenergyid int, -- For 'fere' standards only:
-- the mident having the min energyperatom,
-- for this [symgroupnum, formula, pseudos,
-- lastName, firstName]
enthalpy double precision, -- FERE enthalpy of formation per atom, eV
magneticmoment double precision, -- magnetic moment
initialspacegroupname text, -- initial space group name
initialspacegroupnum int, -- initial space group number
finalspacegroupname text, -- final space group name
finalspacegroupnum int, -- final space group number
parentids int[], -- midents corresponding to meta_parents
familyid int, -- mident of top ancestor on parentids chain
--- metadata ---
hashstring text, -- sha512 of our vasprun.xml
meta_parents text[], -- sha512 of parent vasprun.xml, or null
meta_firstName text, -- metadata: first name
meta_lastName text, -- metadata: last name
meta_publications text[], -- metadata: publication DOI or placeholder
meta_standards text[], -- metadata: controlled vocab keywords
-- See: wrapUpload.py: parseMetadata:
-- legalStandards
meta_keywords text[], -- metadata: uncontrolled vocab keywords
meta_notes text -- metadata: notes
)
''' % (dbtablemodel,))
if useCommit:
conn.commit()
print 'fillDbVasp: table \"%s\" created' % (dbtablemodel,)
ixName = '%s_mident_index' % (dbtablemodel,)
cursor.execute('''
CREATE INDEX %s ON %s (mident)
''' % (ixName, dbtablemodel,))
if useCommit:
conn.commit()
print 'fillDbVasp: index \"%s\" created' % (ixName,)
ixName = '%s_icsdnum_index' % (dbtablemodel,)
cursor.execute('''
CREATE INDEX %s ON %s (icsdnum)
''' % (ixName, dbtablemodel,))
if useCommit:
conn.commit()
print 'fillDbVasp: index \"%s\" created' % (ixName,)
ixName = '%s_hashstring_index' % (dbtablemodel,)
cursor.execute('''
CREATE INDEX %s ON %s (hashstring)
''' % (ixName, dbtablemodel,))
if useCommit:
conn.commit()
print 'fillDbVasp: index \"%s\" created' % (ixName,)
#====================================================================
[docs]def fillRow(
bugLev,
useCommit,
requireIcsd,
allowExc,
modType,
readType,
wrapId,
topDir,
curDir,
conn,
cursor,
dbschema,
dbtablemodel):
'''
Adds one row to the model table, corresponding to relDir.
**Parameters**:
* bugLev (int): Debug level. Normally 0.
* useCommit (boolean): If True, we commit changes to the DB.
* requireIcsd (boolean): if True, the absTopDir string must
contain ICSD info that :func:`getIcsdMap` can extract.
* allowExc (boolean): If True, we continue after an error.
* modType (string): SQL mod type: insert or update.
* readType (string): If outcar use OUTCAR; if xml use vasprun.xml.
* wrapId (str): Arbitrary name for this set of data.
* topDir (str): Original top dir. We ingest all dirs in
this tree containing a metadata file.
* curDir (str): Input directory tree. We ingest all dirs in
this tree containing a metadata file.
* conn (psycopg2.connection): Open DB connection
* cursor (psycopg2.cursor): Open DB cursor
* dbschema (str): Database schema name
* dbtablemodel (str): Database name of the "model" table.
**Returns**
* None
'''
if bugLev >= 1:
print 'fillRow: topDir: %s' % (topDir,)
print 'fillRow: curDir: %s' % (curDir,)
curDir = os.path.abspath( curDir)
if bugLev >= 1:
print 'fillRow: abs: %s' % (curDir,)
cursor.execute('set search_path to %s', (dbschema,))
if not curDir.startswith( topDir):
throwerr('invalid dirs:\n topDir: %s\n curDir: %s\n' % (topDir, curDir,))
relDir = curDir[ len(topDir) : ]
if relDir.startswith('/'): relDir = relDir[1:]
if bugLev >= 1:
print 'fillRow: relDir: %s' % ( relDir,)
# Check curDir
if curDir != os.path.abspath( curDir):
throwerr('curDir not abs: %s' % (curDir,))
mpath = os.path.join( curDir, wrapUpload.metadataName)
metaMap = wrapUpload.parseMetadata( mpath)
if bugLev >= 5:
wrapUpload.printMap('fillRow: metaMap', metaMap, 100)
if requireIcsd:
icsdMap = wrapUpload.getIcsdMap( bugLev, curDir)
else: icsdMap = {}
# Get the hash digest of vasprun.xml or OUTCAR
if readType == 'outcar': tname = outcarName
elif readType == 'xml': tname = vasprunName
else: throwerr('invalid readType: %s' % (readType,))
vname = os.path.join( curDir, tname)
hash = hashlib.sha512()
with open( vname) as fin:
while True:
stg = fin.read()
if stg == '': break
hash.update( stg)
hashString = hash.hexdigest()
# Check our hashString.
# If insert, it must not be in the database
# If update, it must be in the database
cursor.execute( 'SELECT mident, relpath FROM ' + dbtablemodel
+ ' WHERE hashString = %s', (hashString,))
msg = cursor.statusmessage
if not msg.startswith('SELECT'):
throwerr('bad cursor.statusmessage: %s' % (msg,))
rows = cursor.fetchall()
if modType == 'insert': # If this is insert new ...
if len(rows) > 0:
msg = 'Duplicate hashString.\n'
msg += ' hashString: %s\n' % (hashString,)
for ii in range(len(rows)):
msg += ' old mident: %s\n' % (rows[ii][0],)
msg += ' old relPath: %s\n' % (rows[ii][1],)
msg += '\n'
msg += ' wrapId: %s\n' % (wrapId,)
msg += ' relDir: %s\n' % (relDir,)
throwerr( msg)
elif modType == 'update': # If this is update ...
if len(rows) == 0:
msg = 'Update hashString not found.\n'
msg += ' hashString: %s\n' % (hashString,)
msg += ' wrapId: %s\n' % (wrapId,)
msg += ' relDir: %s\n' % (relDir,)
throwerr( msg)
if len(rows) > 1:
msg = 'Multiple hashStrings found.\n'
msg += ' hashString: %s\n' % (hashString,)
for ii in range(len(rows)):
msg += ' old mident: %s\n' % (rows[ii][0],)
msg += ' old relPath: %s\n' % (rows[ii][1],)
msg += '\n'
msg += ' wrapId: %s\n' % (wrapId,)
msg += ' relDir: %s\n' % (relDir,)
throwerr( msg)
else: throwerr('unknown modType')
# Check that parent hashString is in the database
if metaMap.has_key('parent'):
for parentHash in metaMap['parent']:
cursor.execute( 'SELECT mident, relpath FROM ' + dbtablemodel
+ ' WHERE hashString = %s', (parentHash,))
msg = cursor.statusmessage
if msg != 'SELECT': throwerr('bad statusmessage')
rows = cursor.fetchall()
if len(rows) != 1:
msg = 'Parent hashString not found in DB.\n'
msg += ' wrapId: %s\n' % (wrapId,)
msg += ' relDir: %s\n' % (relDir,)
msg += ' our hashString: %s\n' % (hashString,)
msg += ' parent hashString: %s\n' % (parentHash,)
throwerr( msg)
# Read and parse OUTCAR or vasprun.xml, depending on readType
vaspObj = readVasp.parseDir( bugLev, readType, allowExc,
curDir, -1) # print = -1
doscarPath = os.path.join( curDir, 'DOSCAR')
if os.path.isfile( doscarPath):
vaspObj.dosMat = ScanDoscar.scanDoscar( bugLev, doscarPath)
print 'fillRow: dosMat.shape: %s' % (vaspObj.dosMat.shape,)
else:
vaspObj.dosMat = None
print 'fillRow: dosMat is None'
typeNums = getattr( vaspObj, 'typeNums', None)
numAtom = None
if typeNums != None: numAtom = sum( typeNums)
energyNoEntrp = None
eners = getattr( vaspObj, 'energyNoEntrps', None)
if eners != None: energyNoEntrp = eners[-1]
energyPerAtom = None
if numAtom != None and energyNoEntrp != None:
energyPerAtom = energyNoEntrp / numAtom
colNames = ''' (
wrapid,
abspath,
relpath,
icsdNum,
magType,
magNum,
relaxType,
relaxNum,
excMsg,
excTrace,
runDate,
iterRealTimes,
iterTotalTime,
systemName,
encut_ev,
ibrion,
isif,
numSpin,
numKpoint,
numBand,
numAtom,
typeNames,
typeNums,
typeMasses_amu,
typePseudos,
typeValences,
atomNames,
atomMasses_amu,
atomPseudos,
atomValences,
initialBasisMat,
initialRecipBasisMat,
initialCartPosMat,
initialFracPosMat,
finalBasisMat,
finalRecipBasisMat,
finalCartPosMat,
finalFracPosMat,
numElectron,
totalValence,
netCharge,
finalVolume_ang3,
finalDensity_g_cm3,
finalForceMat_ev_ang,
finalStressMat_kbar,
finalPressure_kbar,
eigenMat,
occupMat,
dielectricImag,
dielectricReal,
dosMat,
energyNoEntrp,
energyPerAtom,
efermi0,
scalefactor,
ismear,
sigma,
ldautype,
ldaul_mat,
ldauu_mat,
ldauj_mat,
ldauo_mat,
hashstring, -- sha512 of our vasprun.xml
meta_parents, -- sha512 of parent vasprun.xml, or null
meta_firstName, -- metadata: first name
meta_lastName, -- metadata: last name
meta_publications, -- metadata: publication DOI or placeholder
meta_standards, -- metadata: controlled vocab keywords
meta_keywords, -- metadata: uncontrolled vocab keywords
meta_notes) -- metadata: notes
'''
colToks = ''' (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) '''
if modType == 'insert': # If this is insert new ...
queryStg = 'insert into %s %s values %s' \
% (dbtablemodel, colNames, colToks,)
elif modType == 'update': # If this is update ...
queryStg = 'update %s set %s = %s where hashstring = \'%s\'' \
% (dbtablemodel, colNames, colToks, hashString)
else: throwerr('unknown modType')
cursor.execute(
queryStg,
( wrapId,
None, # absPath xxxx del all abspath
relDir,
icsdMap.get('icsdNum', None),
icsdMap.get('magType', None),
icsdMap.get('magNum', None),
icsdMap.get('relaxType', None),
icsdMap.get('relaxNum', None),
vaspObj.excMsg,
vaspObj.excTrace,
getattr( vaspObj, 'runDate', None),
getattr( vaspObj, 'iterRealTimes', None),
getattr( vaspObj, 'iterTotalTime', None),
getattr( vaspObj, 'systemName', None),
getattr( vaspObj, 'encut_ev', None),
getattr( vaspObj, 'ibrion', None),
getattr( vaspObj, 'isif', None),
getattr( vaspObj, 'numSpin', None),
getattr( vaspObj, 'numKpoint', None),
getattr( vaspObj, 'numBand', None),
numAtom,
getattr( vaspObj, 'typeNames', None),
getattr( vaspObj, 'typeNums', None),
getattr( vaspObj, 'typeMasses_amu', None),
getattr( vaspObj, 'typePseudos', None),
getattr( vaspObj, 'typeValences', None),
getattr( vaspObj, 'atomNames', None),
getattr( vaspObj, 'atomMasses_amu', None),
getattr( vaspObj, 'atomPseudos', None),
getattr( vaspObj, 'atomValences', None),
getattr( vaspObj, 'initialBasisMat', None),
getattr( vaspObj, 'initialRecipBasisMat', None),
getattr( vaspObj, 'initialCartPosMat', None),
getattr( vaspObj, 'initialFracPosMat', None),
getattr( vaspObj, 'finalBasisMat', None),
getattr( vaspObj, 'finalRecipBasisMat', None),
getattr( vaspObj, 'finalCartPosMat', None),
getattr( vaspObj, 'finalFracPosMat', None),
getattr( vaspObj, 'numElectron', None),
getattr( vaspObj, 'totalValence', None),
getattr( vaspObj, 'netCharge', None),
getattr( vaspObj, 'finalVolume_ang3', None),
getattr( vaspObj, 'finalDensity_g_cm3', None),
getattr( vaspObj, 'finalForceMat_ev_ang', None),
getattr( vaspObj, 'finalStressMat_kbar', None),
getattr( vaspObj, 'finalPressure_kbar', None),
getattr( vaspObj, 'eigenMat', None),
getattr( vaspObj, 'occupMat', None),
getattr( vaspObj, 'dielectricImag', None),
getattr( vaspObj, 'dielectricReal', None),
getattr( vaspObj, 'dosMat', None),
energyNoEntrp,
energyPerAtom,
getattr( vaspObj, 'efermi0', None),
getattr( vaspObj, 'posScaleFactor', None),
getattr( vaspObj, 'ismear', None),
getattr( vaspObj, 'sigma', None),
getattr( vaspObj, 'ldautype', None),
getattr( vaspObj, 'ldaul_mat', None),
getattr( vaspObj, 'ldauu_mat', None),
getattr( vaspObj, 'ldauj_mat', None),
getattr( vaspObj, 'ldauo_mat', None),
hashString,
metaMap.get('parents', None),
metaMap['firstName'],
metaMap['lastName'],
metaMap['publications'],
metaMap['standards'],
metaMap['keywords'],
metaMap['notes'],
))
if useCommit:
conn.commit()
#====================================================================
# xxx: special case for None? ... format as NULL?
[docs]def throwerr( msg):
'''
Prints an error message and raises Exception.
**Parameters**:
* msg (str): Error message.
**Returns**
* (Never returns)
**Raises**
* Exception
'''
print msg
print >> sys.stderr, msg
raise Exception( msg)
#====================================================================
if __name__ == '__main__': main()
#====================================================================