Commit 9ed043f6 authored by Ask Hjorth Larsen's avatar Ask Hjorth Larsen
Browse files

better handling of upper/lowercase. Remove duplicate files in tests

parent 735aaa0b
...@@ -48,10 +48,16 @@ def get_input_metadata(inputvars_file, use_new_format): ...@@ -48,10 +48,16 @@ def get_input_metadata(inputvars_file, use_new_format):
varset = set(varlist) varset = set(varlist)
lower_vars = {}
for var in varlist:
lower_vars[var.lower()] = var
def addvar(tokens): def addvar(tokens):
name = tokens[0] name = tokens[0]
val = ' '.join(tokens[1:]) val = ' '.join(tokens[1:])
if name in varset: name = name.lower()
if name in lower_vars:
name = lower_vars[name]
inputvars[name] = val inputvars[name] = val
currentblock = None currentblock = None
...@@ -119,12 +125,12 @@ class SiestaContext(object): ...@@ -119,12 +125,12 @@ class SiestaContext(object):
self.files = None # Dict of files self.files = None # Dict of files
self.blocks = None # Dict of input blocks (coords, cell, etc.) self.blocks = None # Dict of input blocks (coords, cell, etc.)
self._is_last_configuration = False # XXX
self.data = {} self.data = {}
self.special_input_vars = {} self.special_input_vars = {}
self.system_meta = {} self.system_meta = {}
self.section_refs = {} # {name: gindex, ...} self.section_refs = {} # {name: gindex, ...}
self.simulation_type = None
def adhoc_format_new(self, parser): def adhoc_format_new(self, parser):
assert self.format is None assert self.format is None
...@@ -156,51 +162,57 @@ class SiestaContext(object): ...@@ -156,51 +162,57 @@ class SiestaContext(object):
# what else? We already get force/stress/positions from stdout. # what else? We already get force/stress/positions from stdout.
if self.format == 'new': if self.format == 'new':
inplogfiles = glob('%s/fdf-*.log' % dirname) inplogfiles = glob('%s/fdf-*.log' % dirname)
assert len(inplogfiles) == 1
if inplogfiles: if inplogfiles:
inplogfiles.sort() inplogfiles.sort()
files['inputlog'] = inplogfiles[-1] files['inputlog'] = inplogfiles[0]
else: else:
assert self.format == 'old', self.format assert self.format == 'old', self.format
files['inputlog'] = os.path.join(dirname, 'out.fdf') files['inputlog'] = os.path.join(dirname, 'out.fdf')
self.files = files self.files = files
def adhoc_set_simulation_type(self, parser):
line = parser.fIn.readline()
if self.simulation_type is not None:
return
line = line.strip()
if line.startswith('Single-point'):
self.simulation_type = 'singlepoint'
elif 'opt' in line or 'move' in line:
self.simulation_type = 'optimization'
else:
raise ValueError('Todo: recognize simulation type "%s"' % line)
def startedParsing(self, fname, parser): def startedParsing(self, fname, parser):
self.fname = fname self.fname = fname
path = os.path.abspath(fname) path = os.path.abspath(fname)
self.dirname, _ = os.path.split(path) self.dirname, _ = os.path.split(path)
#self.parser = parser #self.parser = parser
def onClose_x_siesta_section_xc_authors(self, backend, gindex, section): #def onClose_x_siesta_section_xc_authors(self, backend, gindex, section):
authors = section['x_siesta_xc_authors']
if authors is None:
raise ValueError('XC authors not found!')
assert len(authors) == 1 def onClose_section_frame_sequence(self, backend, gindex, section):
authors = authors[0] backend.addValue('frame_sequence_to_sampling_ref',
self.section_refs['sampling_method'])
mapping = {'CA': ('LDA_X', 'LDA_C_PZ'), def onOpen_section_sampling_method(self, backend, gindex, section):
'PZ': ('LDA_X', 'LDA_C_PZ'), self.section_refs['sampling_method'] = gindex
'PW92': ('LDA_X', 'LDA_C_PW'),
#'PW91': '',
'PBE': ('GGA_X_PBE', 'GGA_C_PBE'),
'revPBE': ('GGA_X_PBE_R', 'GGA_C_PBE'),
'RPBE': ('GGA_X_RPBE', 'GGA_C_PBE'),
#'WC': ('GGA_X_WC', ),
# Siesta does not mention which correlation is used with
# the WC functional. Is it just the PBE one?
'AM05': ('GGA_X_AM05', 'GGA_C_AM05'),
'PBEsol': ('GGA_X_PBE_SOL', 'GGA_C_PBE_SOL'),
'BLYP': ('GGA_X_B88 + GGA_C_LYP')}
xc = mapping.get(authors)
if xc is None: def onOpen_section_frame_sequence(self, backend, gindex, section):
raise ValueError('XC functional %s unsupported by parser' self.section_refs['frame_sequence'] = gindex
% authors)
for funcname in xc: def onClose_section_sampling_method(self, backend, gindex, section):
gid = backend.openSection('section_XC_functionals') simtype = self.simulation_type
backend.addValue('XC_functional_name', funcname) assert simtype is not None
backend.closeSection('section_XC_functionals', gid) if simtype == 'optimization':
backend.addValue('sampling_method', 'geometry_optimization')
elif simtype == 'singlepoint':
pass
else:
raise ValueError('XXX: %s' % simtype)
def onClose_section_eigenvalues(self, backend, gindex, section): def onClose_section_eigenvalues(self, backend, gindex, section):
self.read_eigenvalues(backend) self.read_eigenvalues(backend)
...@@ -208,6 +220,18 @@ class SiestaContext(object): ...@@ -208,6 +220,18 @@ class SiestaContext(object):
def onOpen_section_method(self, backend, gindex, section): def onOpen_section_method(self, backend, gindex, section):
self.section_refs['method'] = gindex self.section_refs['method'] = gindex
def onClose_section_method(self, backend, gindex, section):
temp = self.special_input_vars['ElectronicTemperature']
temp, unit = temp.split()
assert unit == 'Ry' # Siesta always converts to Ry here I think
temp = float(temp)
temp = convert_unit(temp, 'rydberg')
backend.addValue('smearing_width', temp)
#simtype = self.special_input_vars['MD.TypeOfRun']
#print('SIMTYPE', simtype)
#sdfsdf
def onOpen_section_system(self, backend, gindex, section): def onOpen_section_system(self, backend, gindex, section):
self.section_refs['system'] = gindex self.section_refs['system'] = gindex
...@@ -308,7 +332,7 @@ class SiestaContext(object): ...@@ -308,7 +332,7 @@ class SiestaContext(object):
def onClose_x_siesta_section_input(self, backend, gindex, section): def onClose_x_siesta_section_input(self, backend, gindex, section):
inputvars_file = self.files.get('inputlog') inputvars_file = self.files.get('inputlog')
if inputvars_file is None: if inputvars_file is None:
return raise ValueError('no input logfile!')
inputvars, blocks = get_input_metadata(inputvars_file, inputvars, blocks = get_input_metadata(inputvars_file,
self.format == 'new') self.format == 'new')
...@@ -317,11 +341,44 @@ class SiestaContext(object): ...@@ -317,11 +341,44 @@ class SiestaContext(object):
for special_name in ['LatticeConstant', for special_name in ['LatticeConstant',
'AtomicCoordinatesFormat', 'AtomicCoordinatesFormat',
'AtomicCoordinatesFormatOut']: 'AtomicCoordinatesFormatOut',
'ElectronicTemperature']:
self.special_input_vars[special_name] = inputvars.get(special_name) self.special_input_vars[special_name] = inputvars.get(special_name)
self.blocks = blocks self.blocks = blocks
authors = section['x_siesta_xc_authors']
if authors is None:
raise ValueError('XC authors not found!')
assert len(authors) == 1
authors = authors[0]
# XXX Case sensitive?
mapping = {'CA': ('LDA_X', 'LDA_C_PZ'),
'PZ': ('LDA_X', 'LDA_C_PZ'),
'PW92': ('LDA_X', 'LDA_C_PW'),
#'PW91': '',
'PBE': ('GGA_X_PBE', 'GGA_C_PBE'),
'revPBE': ('GGA_X_PBE_R', 'GGA_C_PBE'),
'RPBE': ('GGA_X_RPBE', 'GGA_C_PBE'),
#'WC': ('GGA_X_WC', ),
# Siesta does not mention which correlation is used with
# the WC functional. Is it just the PBE one?
'AM05': ('GGA_X_AM05', 'GGA_C_AM05'),
'PBEsol': ('GGA_X_PBE_SOL', 'GGA_C_PBE_SOL'),
'BLYP': ('GGA_X_B88 + GGA_C_LYP')}
xc = mapping.get(authors)
if xc is None:
raise ValueError('XC functional %s unsupported by parser'
% authors)
for funcname in xc:
gid = backend.openSection('section_XC_functionals')
backend.addValue('XC_functional_name', funcname)
backend.closeSection('section_XC_functionals', gid)
def read_eigenvalues(self, backend): def read_eigenvalues(self, backend):
eigfile = self.files.get('EIG') eigfile = self.files.get('EIG')
if eigfile is None: if eigfile is None:
...@@ -448,35 +505,47 @@ def get_header_matcher(): ...@@ -448,35 +505,47 @@ def get_header_matcher():
return m return m
def anycase(string):
tokens = []
for letter in list(string):
if letter.isalpha():
tokens.append('[%s%s]' % (letter.upper(),
letter.lower()))
else:
tokens.append(letter)
return ''.join(tokens)
welcome_pattern = r'\s*\*\s*WELCOME TO SIESTA\s*\*' welcome_pattern = r'\s*\*\s*WELCOME TO SIESTA\s*\*'
def get_input_matcher(): def get_input_matcher():
m = SM(welcome_pattern, m = SM(welcome_pattern,
name='welcome', name='welcome',
sections=['section_method'], sections=['section_method', 'x_siesta_section_input'],
fixedStartValues={'electronic_structure_method': 'DFT',
'smearing_kind': 'fermi'},
subFlags=SM.SubFlags.Unordered, subFlags=SM.SubFlags.Unordered,
subMatchers=[ subMatchers=[
SM(r'NumberOfAtoms\s*(?P<number_of_atoms>\d+)', SM(r'NumberOfAtoms\s*(?P<number_of_atoms>\d+)',
name='natoms'), name='natoms'),
context.multi_sm('block_species_label', context.multi_sm('block_species_label',
r'%block ChemicalSpeciesLabel', anycase(r'%block ChemicalSpeciesLabel'),
r'\s*\d+\s*\d+\s*(\S+)', r'\s*\d+\s*\d+\s*(\S+)',
conflict='keep'), conflict='keep'),
context.multi_sm('block_coords_and_species', context.multi_sm('block_coords_and_species',
r'%block AtomicCoordinatesAndAtomicSpecies', anycase(r'%block AtomicCoordinatesAndAtomicSpecies'),
r'\s*(\S+)\s*(\S+)\s*(\S+)\s*(\d+)'), r'\s*(\S+)\s*(\S+)\s*(\S+)\s*(\d+)'),
context.multi_sm('block_lattice_vectors', context.multi_sm('block_lattice_vectors',
r'%block LatticeVectors', anycase(r'%block LatticeVectors'),
r'(?!%)\s*(\S+)\s*(\S+)\s*(\S+)'), r'(?!%)\s*(\S+)\s*(\S+)\s*(\S+)'),
SM(r'xc.authors\s*(?P<x_siesta_xc_authors>\S+)', SM(r'%s\s*(?P<x_siesta_xc_authors>\S+)' % anycase('xc\.authors'),
name='xc authors', name='xc authors',
fixedStartValues={'x_siesta_xc_authors': 'CA'}, fixedStartValues={'x_siesta_xc_authors': 'CA'}),
sections=['section_method', 'x_siesta_section_xc_authors']), #SM(r'MD.TypeOfRun\s*(?P<x_siesta_typeofrun>\S+)',
# fixedStartValues={'x_siesta_typeofrun': 'none'}),
SM(r'reinit: System Name:\s*(?P<system_name>.+)', SM(r'reinit: System Name:\s*(?P<system_name>.+)',
name='sysname'), name='sysname'),
SM(r'reinit: System Label:\s*(?P<x_siesta_system_label>\S+)', SM(r'reinit: System Label:\s*(?P<x_siesta_system_label>\S+)',
name='syslabel', forwardMatch=True, name='syslabel', forwardMatch=True,
sections=['x_siesta_section_input'],
adHoc=context.adhoc_set_label), adHoc=context.adhoc_set_label),
context.multi_sm('coords_and_species', context.multi_sm('coords_and_species',
r'siesta: Atomic coordinates \(Bohr\) and species', r'siesta: Atomic coordinates \(Bohr\) and species',
...@@ -495,6 +564,8 @@ step_pattern = r'\s*(Single-point calculation|Begin[^=]+=\s*\d+)' ...@@ -495,6 +564,8 @@ step_pattern = r'\s*(Single-point calculation|Begin[^=]+=\s*\d+)'
def get_step_matcher(): def get_step_matcher():
m = SM(step_pattern, m = SM(step_pattern,
name='step', name='step',
forwardMatch=True,
adHoc=context.adhoc_set_simulation_type,
sections=['section_single_configuration_calculation'], sections=['section_single_configuration_calculation'],
subFlags=SM.SubFlags.Unordered, subFlags=SM.SubFlags.Unordered,
subMatchers=[ subMatchers=[
...@@ -547,7 +618,7 @@ mainFileDescription = SM( ...@@ -547,7 +618,7 @@ mainFileDescription = SM(
forwardMatch=True, forwardMatch=True,
repeats=True, repeats=True,
required=True, required=True,
sections=['section_system'], sections=['section_system', 'section_frame_sequence', 'section_sampling_method'],
subMatchers=[ subMatchers=[
get_input_matcher(), get_input_matcher(),
get_step_matcher(), get_step_matcher(),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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