Commit ce07a7cc authored by Carl Poelking's avatar Carl Poelking
Browse files

XML parsing.

parent 12e80786
...@@ -66,18 +66,20 @@ def parse(output_file_name): ...@@ -66,18 +66,20 @@ def parse(output_file_name):
jbe.startedParsingSession(output_file_name, parser_info) jbe.startedParsingSession(output_file_name, parser_info)
base_dir = os.path.dirname(os.path.abspath(output_file_name)) base_dir = os.path.dirname(os.path.abspath(output_file_name))
terminal = LibAtomsParser(osio) terminal_gap = LibAtomsGapParser(osio)
terminal_trj = LibAtomsTrajectory(osio) terminal_gap.ParseOutput(output_file_name)
terminal_trj.ParseOutput(output_file_name) terminal_trj = terminal_gap.trj
out = terminal
osio << "Start parsing ..." << osio.endl
osio << "Base directory = '%s'" % base_dir << osio.endl
gap = terminal_gap
trj = terminal_trj trj = terminal_trj
log("Start parsing ...")
log("Base directory = '%s'" % base_dir)
with open_section(jbe, 'section_run') as gid_run: with open_section(jbe, 'section_run') as gid_run:
push(jbe, trj, 'program_name') push(jbe, gap, 'program_name')
push(jbe, trj, 'program_version') push(jbe, gap, 'program_version', key2='GAP_params.svn_version')
jbe.finishedParsingSession("ParseSuccess", None) jbe.finishedParsingSession("ParseSuccess", None)
return return
......
...@@ -8,6 +8,7 @@ import os ...@@ -8,6 +8,7 @@ import os
import sys import sys
import re import re
import numpy as np import numpy as np
import xml.dom.minidom
try: try:
import ase import ase
...@@ -17,6 +18,36 @@ except ImportError: ...@@ -17,6 +18,36 @@ except ImportError:
HAVE_ASE = False HAVE_ASE = False
pass pass
def XmlGetUnique(root, tag):
nodes = XmlGetAll(root, tag)
if len(nodes) > 1:
raise ValueError("More than one node with tag '%s'" % tag)
return nodes[0]
def XmlGetAll(root, tag):
nodes = root.getElementsByTagName(tag)
ret_nodes = []
for node in nodes:
if node.localName != None: ret_nodes.append(node)
return ret_nodes
def XmlGetChildDict(root):
tag_child = {}
for child in root.childNodes:
if child.localName == None: continue
if not child.localName in tag_child:
tag_child[child.localName] = []
tag_child[child.localName].append(child)
return tag_child
def XmlGetAttributes(root):
return root.attributes
def XmlGetText(root):
return root.firstChild.nodeValue
class LibAtomsParser(object): class LibAtomsParser(object):
def __init__(self, log=None): def __init__(self, log=None):
self.log = log self.log = log
...@@ -33,7 +64,7 @@ class LibAtomsParser(object): ...@@ -33,7 +64,7 @@ class LibAtomsParser(object):
return self return self
def As(self, typ=None): def As(self, typ=None):
if typ == None: if typ == None:
typ = type(self.selected_data_item) return self.selected_data_item
return typ(self.selected_data_item) return typ(self.selected_data_item)
def SummarizeKeyDefaults(self): def SummarizeKeyDefaults(self):
if not self.log: return if not self.log: return
...@@ -140,15 +171,125 @@ class LibAtomsParser(object): ...@@ -140,15 +171,125 @@ class LibAtomsParser(object):
self.Set('program_version', 'n/a') self.Set('program_version', 'n/a')
return return
class LibAtomsGapParser(LibAtomsParser):
def __init__(self, log=None):
super(LibAtomsGapParser, self).__init__(log)
self.logtag = 'gap-xml'
self.trj = None
return
def ParseOutput(self, output_file):
self.Set('program_name', 'libAtoms')
dom = xml.dom.minidom.parse(output_file)
root = XmlGetUnique(dom, 'GAP_params')
# Child keys should be: ['gpSparse', 'command_line', 'GAP_data', 'XYZ_data']
#print(list(child_nodes.keys()))
child_nodes = XmlGetChildDict(root)
# 'GAP_params'
atts = XmlGetAttributes(root)
keys = ['label', 'svn_version']
for key in keys:
self.Set('GAP_params.%s' % key, atts[key].value) # TODO Handle look-up errors
# 'GAP_params/GAP_data'
key = 'GAP_data'
if key in child_nodes:
node = child_nodes[key][0]
atts = XmlGetAttributes(node)
keys = ['do_core', 'e0']
for key in keys:
self.Set('GAP_data.%s' % key, atts[key].value) # TODO Handle look-up errors
# 'GAP_params/command_line'
key = 'command_line'
if key in child_nodes:
node = child_nodes[key][0]
text = XmlGetText(node)
self.Set('command_line.command_line', text)
# 'GAP_params/gpSparse'
key = 'gpSparse'
if key in child_nodes:
node = child_nodes[key][0]
atts = XmlGetAttributes(node)
keys = ['n_coordinate']
for key in keys:
self.Set('gpSparse.%s' % key, atts[key].value) # TODO Handle look-up errors
# GAP_params/gpSparse/gpCoordinates
gp_coord_node = XmlGetUnique(node, 'gpCoordinates')
gp_coord_child_nodes = XmlGetChildDict(gp_coord_node)
gp_coord_node_att = XmlGetAttributes(gp_coord_node)
for key in gp_coord_node_att.keys():
self.Set('gpCoordinates.%s' % key, gp_coord_node_att[key].value)
# 'GAP_params/gpSparse/gpCoordinates/theta
key = 'theta'
if key in gp_coord_child_nodes:
node = gp_coord_child_nodes[key][0]
text = XmlGetText(node).strip()
self.Set('gpCoordinates.%s' % key, text)
# 'GAP_params/gpSparse/gpCoordinates/descriptor
key = 'descriptor'
if key in gp_coord_child_nodes:
node = gp_coord_child_nodes[key][0]
text = XmlGetText(node).strip()
self.Set('gpCoordinates.%s' % key, text)
# 'GAP_params/gpSparse/gpCoordinates/descriptor
key = 'permutation'
if key in gp_coord_child_nodes:
node = gp_coord_child_nodes[key][0]
att = XmlGetAttributes(node)
text = XmlGetText(node).strip()
self.Set('gpCoordinates.perm.%s' % key, text)
self.Set('gpCoordinates.perm.i', att['i'].value)
# 'GAP_params/gpSparse/gpCoordinates/sparseX
key = 'sparseX'
if key in gp_coord_child_nodes:
n_sparseX = self['gpCoordinates.n_sparseX'].As(int)
n_dim = self['gpCoordinates.dimensions'].As(int)
sparseX_filename = self['gpCoordinates.sparseX_filename'].As(str)
# Read alpha coefficients
nodes = gp_coord_child_nodes[key]
alpha_cutoff = np.zeros((n_sparseX, 2), dtype='float64')
for i,node in enumerate(nodes):
att = XmlGetAttributes(node)
alpha_cutoff[i,0] = float(att["alpha"].value)
alpha_cutoff[i,1] = float(att["sparseCutoff"].value)
self.Set('gpCoordinates.alpha', alpha_cutoff)
# Read descriptor matrix
X_matrix = np.loadtxt(sparseX_filename)
assert X_matrix.shape[0] == n_sparseX*n_dim
# i-th row of X-matrix stores X-vector of config i
X_matrix = X_matrix.reshape((n_dim, n_sparseX))
self.Set('gpCoordinates.sparseX', X_matrix)
# 'GAP_params/XYZ_data'
key = 'XYZ_data'
if key in child_nodes:
node = child_nodes[key][0]
text = XmlGetText(node)
trj_file = 'lib-atoms-gap.from-xml.xyz'
ofs = open(trj_file, 'w')
for child in node.childNodes:
if child.nodeValue == None: continue
ln = child.nodeValue.strip(' \n')
if ln == '': continue
ofs.write(ln+'\n')
ofs.close()
self.trj = LibAtomsTrajectory(self.log)
self.trj.ParseOutput(trj_file)
return
class LibAtomsTrajectory(LibAtomsParser): class LibAtomsTrajectory(LibAtomsParser):
def __init__(self, log=None): def __init__(self, log=None):
super(LibAtomsTrajectory, self).__init__(log) super(LibAtomsTrajectory, self).__init__(log)
self.ase_configs = None self.ase_configs = None
self.frames = [] self.frames = []
self.logtag = 'trj'
def ParseOutput(self, output_file): def ParseOutput(self, output_file):
if self.log: if self.log:
self.log << self.log.mg << "libAtomsParser::ParseOutput ..." << self.log.endl self.log << self.log.mg << "libAtomsParser::ParseOutput ..." << self.log.endl
if HAVE_ASE: if HAVE_ASE:
read_fct = ase.io.read read_fct = ase.io.read
read_fct_args = { 'index':':' } read_fct_args = { 'index':':' }
...@@ -156,11 +297,9 @@ class LibAtomsTrajectory(LibAtomsParser): ...@@ -156,11 +297,9 @@ class LibAtomsTrajectory(LibAtomsParser):
raise NotImplementedError("None-ASE read function requested, but not yet available.") raise NotImplementedError("None-ASE read function requested, but not yet available.")
read_fct = None read_fct = None
read_fct_args = None read_fct_args = None
# PARSE CONFIGURATIONS # PARSE CONFIGURATIONS
self.ase_configs = read_fct(output_file, **read_fct_args) self.ase_configs = read_fct(output_file, **read_fct_args)
self.LoadAseConfigs(self.ase_configs) self.LoadAseConfigs(self.ase_configs)
self.Set('program_name', 'libAtoms') self.Set('program_name', 'libAtoms')
self.Set('program_version', 'n/a') self.Set('program_version', 'n/a')
return return
...@@ -169,7 +308,7 @@ class LibAtomsTrajectory(LibAtomsParser): ...@@ -169,7 +308,7 @@ class LibAtomsTrajectory(LibAtomsParser):
frame = LibAtomsFrame(self.log) frame = LibAtomsFrame(self.log)
frame.LoadAseConfig(config) frame.LoadAseConfig(config)
self.frames.append(frame) self.frames.append(frame)
if self.log: log << "Loaded %d configurations" % len(self.frames) << log.endl if self.log: self.log << "Loaded %d configurations" % len(self.frames) << self.log.endl
return return
class LibAtomsFrame(LibAtomsParser): class LibAtomsFrame(LibAtomsParser):
......
...@@ -425,7 +425,7 @@ class ShellInterface(object): ...@@ -425,7 +425,7 @@ class ShellInterface(object):
try: try:
height, width = os.popen('stty size', 'r').read().split() height, width = os.popen('stty size', 'r').read().split()
width = int(width) width = int(width)
leftright = ((width - len(title)-2) // 2 leftright = ((width - len(title)-2)) // 2
except ValueError: except ValueError:
leftright = 40 leftright = 40
return trim*leftright + " " + title + " " + trim*leftright return trim*leftright + " " + title + " " + trim*leftright
......
...@@ -21,7 +21,7 @@ object LibAtomsParser extends SimpleExternalParserGenerator( ...@@ -21,7 +21,7 @@ object LibAtomsParser extends SimpleExternalParserGenerator(
)) :: Nil )) :: Nil
), ),
mainFileTypes = Seq("text/.*"), mainFileTypes = Seq("text/.*"),
mainFileRe = """ ll """.r, mainFileRe = """\s*<GAP_params\s""".r,
cmd = Seq(DefaultPythonInterpreter.pythonExe(), "${envDir}/parsers/lib-atoms/parser/parser-lib-atoms/libAtomsParser.py", cmd = Seq(DefaultPythonInterpreter.pythonExe(), "${envDir}/parsers/lib-atoms/parser/parser-lib-atoms/libAtomsParser.py",
"${mainFilePath}"), "${mainFilePath}"),
resList = Seq( resList = Seq(
......
...@@ -5,10 +5,10 @@ import org.specs2.mutable.Specification ...@@ -5,10 +5,10 @@ import org.specs2.mutable.Specification
object LibAtomsParserSpec extends Specification { object LibAtomsParserSpec extends Specification {
"LibAtomsParserTest" >> { "LibAtomsParserTest" >> {
"test with json-events" >> { "test with json-events" >> {
ParserRun.parse(LibAtomsParser, "parsers/lib-atoms/test/lib-atoms-tungsten/tungsten_gap_6.xyz", "json-events") must_== ParseResult.ParseSuccess ParserRun.parse(LibAtomsParser, "parsers/lib-atoms/test/lib-atoms-gap-test/gp.xml", "json-events") must_== ParseResult.ParseSuccess
} }
"test with json" >> { "test with json" >> {
ParserRun.parse(LibAtomsParser, "parsers/lib-atoms/test/lib-atoms-tungsten/tungsten_gap_6.xyz", "json") must_== ParseResult.ParseSuccess ParserRun.parse(LibAtomsParser, "parsers/lib-atoms/test/lib-atoms-gap-test/gp.xml", "json") must_== ParseResult.ParseSuccess
} }
} }
} }
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