Commit ee8dfe6b authored by Ask Hjorth Larsen's avatar Ask Hjorth Larsen

clean up vestigial code from certain octopus parser modules, moving the...

clean up vestigial code from certain octopus parser modules, moving the remainder into the main module
parent 1153f1db
from __future__ import print_function
from builtins import object
import logging
import setup_paths
from nomadcore.simple_parser import SimpleMatcher as SM
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
from nomadcore.unit_conversion.unit_conversion \
import register_userdefined_quantity, convert_unit
import os, sys, json
from util import OCT_ENERGY_UNIT_NAME, f_num, i_num, numpattern, integer,\
parse_file_without_decorations
# Match lines like: " Total = -7.05183\n"
def oct_energy_sm(octname, nomadname):
pattern = (r'\s*%(octname)s\s*=\s*%(pattern)s'
% dict(octname=octname,
pattern=numpattern(nomadname,
unit=OCT_ENERGY_UNIT_NAME)))
#print 'oct energy sm', pattern
return SM(pattern,
name=octname)
sm_scfconv = SM(r'SCF converged in\s*%s\s*iterations'
% integer('x_octopus_info_scf_converged_iterations'),
sections=['section_run'])
sm_energy = SM(r'Energy \[(H|eV)\]:', required=True, name='energy_header',
subMatchers=[
oct_energy_sm('Total', 'energy_total'),
oct_energy_sm('Free', 'energy_free'),
oct_energy_sm('Ion-ion', 'x_octopus_info_energy_ion_ion'),
oct_energy_sm('Eigenvalues', 'energy_sum_eigenvalues'),
oct_energy_sm('Hartree', 'energy_electrostatic'),
#oct_energy_sm(r'Int\[n.v_xc\]', ''),
oct_energy_sm('Exchange', 'energy_X'),
oct_energy_sm('Correlation', 'energy_C'),
oct_energy_sm('vanderWaals', 'energy_van_der_Waals'),
oct_energy_sm('-TS', 'energy_correction_entropy'),
oct_energy_sm('Kinetic', 'electronic_kinetic_energy')
])
infoFileDescription = SM(
name='root',
weak=True,
startReStr='',
fixedStartValues={'program_name': 'octopus'},
sections=['section_single_configuration_calculation'],
subFlags=SM.SubFlags.Sequenced,
subMatchers=[
sm_scfconv,
sm_energy,
])
parserInfo = {
"name": "info_parser_octopus",
"version": "1.0"
}
class OctopusParserContext(object):
"""main place to keep the parser status, open ancillary files,..."""
def __init__(self):
self.scfIterNr = 0
# just examples, you probably want to remove the following two triggers
def startedParsing(self, name, parser):
pass
def onClose_section_single_configuration_calculation(self, backend, gIndex, section):
"""trigger called when section_single_configuration_calculation is closed"""
pass
#backend.addValue("", self.scfIterNr)
#logging.getLogger("nomadcore.parsing").info("closing section_single_configuration_calculation gIndex %d %s", gIndex, section.simpleValues)
#self.scfIterNr = 0
def onClose_section_scf_iteration(self, backend, gIndex, section):
"""trigger called when section_scf_iteration is closed"""
pass
#logging.getLogger("nomadcore.parsing").info("closing section_scf_iteration bla gIndex %d %s", gIndex, section.simpleValues)
#self.scfIterNr += 1
#def parse_infofile(meta_info_env, pew, fname):
# parse_file_without_decorations(pew, meta_info_env, infoFileDescription,
# parserInfo, OctopusParserContext(), fname)
def parse_infofile(meta_info_env, pew, fname):
with open(fname) as fd:
for line in fd:
if line.startswith('SCF converged'):
iterations = int(line.split()[-2])
pew.addValue('x_octopus_info_scf_converged_iterations',
iterations)
break
for line in fd: # Jump down to energies:
if line.startswith('Energy ['):
octunit = line.strip().split()[-1].strip('[]:')
nomadunit = {'eV': 'eV', 'H': 'hartree'}[octunit]
break
names = {'Total': 'energy_total',
'Free': 'energy_free',
'Ion-ion': 'x_octopus_info_energy_ion_ion',
'Eigenvalues': 'energy_sum_eigenvalues',
'Hartree': 'energy_electrostatic',
'Exchange': 'energy_X',
'Correlation': 'energy_C',
'vanderWaals': 'energy_van_der_Waals',
'-TS': 'energy_correction_entropy',
'Kinetic': 'electronic_kinetic_energy'}
for line in fd:
if line.startswith('---'):
continue
tokens = line.split()
if len(tokens) < 3:
break
if tokens[0] in names:
pew.addValue(names[tokens[0]],
convert_unit(float(tokens[2]), nomadunit))
from nomadcore.simple_parser import mainFunction, SimpleMatcher as SM
from util import numpattern, i_num, f_num, e_num, word, integer, \
parse_file_without_decorations
parserInfo = {
"name": "logfile_parser_octopus",
"version": "1.0"
}
logFileDescription = SM(
name='root',
weak=True,
startReStr='',
fixedStartValues={'program_name': 'octopus'},
#sections=['section_run'],
subFlags=SM.SubFlags.Sequenced,
subMatchers=[
SM(r'Version\s*:\s*%s' % word('program_version')),
#SM(r'Revision\s*:\s*%s' % integer('x_octopus_log_svn_revision')),
]
)
class OctopusLogFileParserContext(object):
def startedParsing(self, name, parser):
pass
def parse_logfile(meta_info_env, pew, fname):
# XXX this is just a hack until we decide to do more
maxlines = 100
with open(fname) as fd:
for i, line in enumerate(fd):
if i > maxlines:
break
if line.startswith('Version'):
version = line.split()[-1]
pew.addValue('program_version', version)
elif line.startswith('Revision'):
revision = int(line.split()[-1])
pew.addValue('x_octopus_log_svn_revision', revision)
# XXX more info
#def parse_logfile(meta_info_env, pew, fname):
# parse_file_without_decorations(pew, meta_info_env, logFileDescription,
# parserInfo, OctopusLogFileParserContext(),
# fname)
......@@ -13,12 +13,9 @@ import setup_paths
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
from nomadcore.parser_backend import JsonParseEventsWriterBackend
from nomadcore.unit_conversion.unit_conversion import convert_unit, \
register_userdefined_quantity
from nomadcore.unit_conversion.unit_conversion import convert_unit
from aseoct import Octopus, parse_input_file
from octopus_info_parser import parse_infofile
from octopus_logfile_parser import parse_logfile
"""This is the Octopus parser.
......@@ -43,6 +40,57 @@ is largely irrelevant.
"""
def parse_infofile(meta_info_env, pew, fname):
with open(fname) as fd:
for line in fd:
if line.startswith('SCF converged'):
iterations = int(line.split()[-2])
pew.addValue('x_octopus_info_scf_converged_iterations',
iterations)
break
for line in fd: # Jump down to energies:
if line.startswith('Energy ['):
octunit = line.strip().split()[-1].strip('[]:')
nomadunit = {'eV': 'eV', 'H': 'hartree'}[octunit]
break
names = {'Total': 'energy_total',
'Free': 'energy_free',
'Ion-ion': 'x_octopus_info_energy_ion_ion',
'Eigenvalues': 'energy_sum_eigenvalues',
'Hartree': 'energy_electrostatic',
'Exchange': 'energy_X',
'Correlation': 'energy_C',
'vanderWaals': 'energy_van_der_Waals',
'-TS': 'energy_correction_entropy',
'Kinetic': 'electronic_kinetic_energy'}
for line in fd:
if line.startswith('---'):
continue
tokens = line.split()
if len(tokens) < 3:
break
if tokens[0] in names:
pew.addValue(names[tokens[0]],
convert_unit(float(tokens[2]), nomadunit))
def parse_logfile(meta_info_env, pew, fname):
maxlines = 100
with open(fname) as fd:
for i, line in enumerate(fd):
if i > maxlines:
break
if line.startswith('Version'):
version = line.split()[-1]
pew.addValue('program_version', version)
elif line.startswith('Revision'):
revision = int(line.split()[-1])
pew.addValue('x_octopus_log_svn_revision', revision)
def parse_gridinfo(metaInfoEnv, pew, fname):
results = {}
......@@ -88,8 +136,6 @@ def parse_gridinfo(metaInfoEnv, pew, fname):
def parse_coordinates_from_parserlog(fname):
results = {}
units = 'bohr'
def buildblock(block):
imax = 1 + max(b[0] for b in block)
jmax = 1 + max(b[1] for b in block)
......@@ -167,10 +213,6 @@ def parse_coordinates_from_parserlog(fname):
def normalize_names(names):
return [name.lower() for name in names]
#ENERGY_UNIT = 'usrOctEnergyUnit'
#LENGTH_UNIT = 'usrOctLengthUnit'
metaInfoPath = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
"../../../../nomad-meta-info/meta_info/nomad_meta_info/octopus.nomadmetainfo.json"))
metaInfoEnv, warnings = loadJsonFile(filePath=metaInfoPath,
......@@ -182,7 +224,6 @@ metaInfoEnv, warnings = loadJsonFile(filePath=metaInfoPath,
metaInfoKinds = metaInfoEnv.infoKinds.copy()
all_metadata_names = list(metaInfoKinds.keys())
normalized2real = dict(zip(normalize_names(all_metadata_names), all_metadata_names))
#assert 'x_octopus_info_scf_converged_iterations' in metaInfoKinds, '\n'.join(list(sorted(metaInfoKinds.keys())))
# We need access to this information because we want/need to dynamically convert
# extracted metadata to its correct type. Thus we need to know the type.
# Also since input is case insensitive, we need to convert normalized (lowercase)
......@@ -211,26 +252,22 @@ def read_parser_log(path):
if ' ' in name:
# Not a real name
continue
#print(name)
# Octopus questionably writes this one twice
#if name != 'speciesprojectorspherethreshold':
exec_kwargs[name] = value
return exec_kwargs
def is_octopus_logfile(fname):
fd = open(fname)
for n, line in enumerate(fd):
if n > 20:
break
if '|0) ~ (0) |' in line: # Eyes from Octopus logo
return True
with open(fname) as fd:
for n, line in enumerate(fd):
if n > 20:
break
if '|0) ~ (0) |' in line: # Eyes from Octopus logo
return True
return False
def find_octopus_logfile(dirname):
allfnames = glob('%s/*' % dirname)
for fname in allfnames:
for fname in os.listdir(dirname):
if os.path.isfile(fname) and is_octopus_logfile(fname):
return fname
return None
......@@ -275,28 +312,6 @@ def override_keywords(kwargs, parser_log_kwargs, fd):
return outkwargs
def register_units(kwargs, fd):
units = kwargs.get('units', 'atomic').lower()
if units == 'atomic':
length_unit = 'bohr'
energy_unit = 'hartree'
elif units == 'ev_angstrom':
length_unit = 'angstrom'
energy_unit = 'eV'
else:
raise ValueError('Unknown units: %s' % units)
if 'unitsinput' in kwargs:
raise ValueError('UnitsInput not supported')
if 'unitsoutput' in kwargs:
raise ValueError('UnitsOutput not supported')
print('Set units: energy=%s, length=%s' % (energy_unit, length_unit),
file=fd)
register_userdefined_quantity(ENERGY_UNIT, energy_unit)
register_userdefined_quantity(LENGTH_UNIT, length_unit)
metadata_dtypes = {'b': bool,
'C': str,
'f': float} # Integer?
......@@ -375,19 +390,12 @@ def parse(fname, fd):
print('Override certain keywords with processed keywords', file=fd)
kwargs = override_keywords(kwargs, parser_log_kwargs, fd)
#register_units(kwargs, fd)
print('Read as ASE calculator', file=fd)
calc = Octopus(dirname, check_keywords=False)
#atoms = calc.get_atoms()
with open_section('section_basis_set_cell_dependent') as basis_set_cell_dependent_gid:
pew.addValue('basis_set_cell_dependent_kind', 'realspace_grids')
# XXX FIXME spacing can very rarely be 3 numbers!
# uuh there is no meaningful way to set grid spacing
# pass
#cubefiles = glob('staticdirname/*.cube')
#cubefiles.sort()
# How does nomad want grid spacing?
nbands = calc.get_number_of_bands()
nspins = calc.get_number_of_spins()
......@@ -506,16 +514,17 @@ def parse(fname, fd):
float(parser_log_kwargs['excesscharge']))
oct_theory_level = kwargs.get('theorylevel', 'dft')
theory_levels = dict(#independent_particles='',
#hartree='',
#hartree_fock='',
dft='DFT')
#classical='',
#rdmft='')
theory_levels = dict(independent_particles='independent_particles', # not defined by Nomad
hartree='Hartree', # not defined by Nomad
hartree_fock='DFT', # nomad wants it that way
dft='DFT',
classical='Classical', # Not defined by Nomad
rdmft='RDMFT') # Not defined by Nomad
# TODO how do we warn if we get an unexpected theory level?
# Currently: KeyError
nomad_theory_level = theory_levels[oct_theory_level]
pew.addValue('electronic_structure_method', 'DFT')
pew.addValue('electronic_structure_method', nomad_theory_level)
if oct_theory_level == 'dft':
ndim = int(kwargs.get('dimensions', 3))
......
......@@ -48,10 +48,8 @@ Simulation Box:
resList = Seq(
"parser-octopus/parser_octopus.py",
"parser-octopus/aseoct.py",
"parser-octopus/octopus_logfile_parser.py",
"parser-octopus/generate-octopus-json.py",
"parser-octopus/util.py",
"parser-octopus/octopus_info_parser.py",
"parser-octopus/setup_paths.py",
"nomad_meta_info/public.nomadmetainfo.json",
"nomad_meta_info/common.nomadmetainfo.json",
......
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