Commit 639a45b1 authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Improved cell parsing, updated NomadParser.

parent e9092f06
......@@ -5,4 +5,4 @@ from cp2kparser.implementation.autoparser import get_parser
# logging.basicConfig(level=logging.INFO)
path = os.getcwd()
parser = get_parser(path)
parser.get_all_quantities()
parser.parse()
......@@ -76,6 +76,11 @@ class Root(object):
if keyword:
return keyword.default_value
def get_default_unit(self, path):
keyword, section = self.get_keyword_and_section(path)
if keyword:
return keyword.default_unit
def get_parameter_and_section(self, path):
section = self.get_section(path)
parameter = section.parameter
......@@ -89,7 +94,6 @@ class Root(object):
elif section and section.accessed:
return parameter.lone_value
# def get_parameter_lone(self, path):
# parameter = self.get_parameter_object(path)
# return parameter.lone_value
......@@ -104,10 +108,17 @@ class Keyword(object):
"""Information about a keyword in a CP2K calculation.
"""
def __init__(self, default_name, default_value):
def __init__(self, default_name, default_value, default_unit_value):
self.value = None
self.default_name = default_name
self.default_value = default_value
self.default_unit = default_unit_value
def get_value():
"""If the units of this value can be changed, return a value and the
unit separately.
"""
pass
#===============================================================================
......
......@@ -68,7 +68,13 @@ def recursive_tree_generation(xml_element):
default_keyword_value = None
if default_keyword_element is not None:
default_keyword_value = default_keyword_element.text
keyword_object = Keyword(default_name, default_keyword_value)
default_unit_element = keyword.find("DEFAULT_UNIT")
default_unit_value = None
if default_unit_element is not None:
default_unit_value = default_unit_element.text
keyword_object = Keyword(default_name, default_keyword_value, default_unit_value)
section.keywords[default_name].append(keyword_object)
for alias in aliases:
section.keywords[alias].append(keyword_object)
......
......@@ -239,8 +239,9 @@ class NomadParser(object):
result = self.results.get(name)
if result is None:
result = self.start_parsing(name)
if result.cache:
self.results[name] = result
if result:
if result.cache:
self.results[name] = result
return result
def result_saver(self, result):
......
......@@ -15,6 +15,7 @@ def scan_path_for_files(path):
".cif",
".pdb",
".dcd",
".cell",
}
files = {}
for filename in os.listdir(path):
......
......@@ -143,37 +143,48 @@ class CP2KParser(NomadParser):
logger.debug("Initial coordinate file found.")
# Check against the given files
file_path = self.search_file(init_coord_file)
self.file_ids["initial_coordinates"] = file_path
self.get_file_handle("initial_coordinates")
self.setup_file_id(file_path, "initial_coordinates")
# Determine the presence of a trajectory file
traj_file = self.input_tree.get_keyword("MOTION/PRINT/TRAJECTORY/FILENAME")
if traj_file is not None:
file_format = self.input_tree.get_keyword("MOTION/PRINT/TRAJECTORY/FORMAT")
extension = {
"PDB": "pdb",
"XYZ": "xyz",
"XMOL": "xyz",
"ATOMIC": "xyz",
"DCD": "dcd",
}[file_format]
logger.debug("Trajectory file found.")
normalized_path = self.normalize_cp2k_traj_path(traj_file)
normalized_path = self.normalize_cp2k_path(traj_file, extension, "pos")
file_path = self.search_file(normalized_path)
self.file_ids["trajectory"] = file_path
self.get_file_handle("trajectory")
self.setup_file_id(file_path, "trajectory")
# Determine the presence of a cell file
cell_motion_file = self.input_tree.get_keyword("MOTION/PRINT/CELL/FILENAME")
if cell_motion_file is not None:
logger.debug("Cell file found.")
extension = "cell"
normalized_path = self.normalize_cp2k_path(cell_motion_file, extension)
print normalized_path
file_path = self.search_file(normalized_path)
self.setup_file_id(file_path, "cell")
def normalize_cp2k_traj_path(self, path):
def normalize_cp2k_path(self, path, extension, name=""):
if name:
name = "-" + name
logger.debug("Normalizing trajectory path")
project_name = self.input_tree.get_keyword("GLOBAL/PROJECT_NAME")
file_format = self.input_tree.get_keyword("MOTION/PRINT/TRAJECTORY/FORMAT")
extension = {
"PDB": "pdb",
"XYZ": "xyz",
"XMOL": "xyz",
"ATOMIC": "xyz",
"DCD": "dcd",
}[file_format]
if path.startswith("="):
normalized_path = path[1:]
elif re.match(r"./", path):
normalized_path = "{}-pos-1.{}".format(path, extension)
normalized_path = "{}{}-1.{}".format(path, name, extension)
else:
normalized_path = "{}-{}-pos-1.{}".format(project_name, path, extension)
normalized_path = "{}-{}{}-1.{}".format(project_name, path, name, extension)
return normalized_path
def search_file(self, path):
"""Searches the list of given files for a file that is defined in the
CP2K input file.
......@@ -262,7 +273,21 @@ class CP2KImplementation(object):
if pint_unit:
return pint_unit
else:
logger.error("Unknown CP2K unit definition given.")
logger.error("Unknown CP2K unit definition '{}'.".format(unit))
def get_cp2k_unit(self, path):
input_value = self.input_tree.get_keyword(path)
unit_definition = input_value.split()[0]
if unit_definition.startswith('[') and unit_definition.endswith(']'):
unit_definition = unit_definition[1:-1]
return self.decode_cp2k_unit(unit_definition)
else:
logger.debug("No special unit definition found, returning default unit.")
unit_definition = self.input_tree.get_default_unit(path)
if unit_definition:
return self.decode_cp2k_unit(unit_definition)
else:
logger.error("Could not deduce the unit of keyword in path '{}'".format(path))
def _Q_energy_total(self):
"""Return the total energy from the bottom of the input file"""
......@@ -489,25 +514,61 @@ class CP2KImplementation(object):
return result
def _Q_cell(self):
"""The cell size can be static or dynamic if e.g. doing NPT.
"""
result = Result()
# Cell given as three vectors
A = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/A")
B = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/B")
C = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/C")
if A and B and C:
return
# Cell given as three lengths and three angles
ABC = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/ABC")
abg = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/ALPHA_BETA_GAMMA")
# Determine if the cell is printed during simulation steps
cell_file = self.parser.get_file_handle("cell")
if cell_file:
logger.debug("Cell motion file found.")
result.unit = ureg.angstrom
# Cell given in external file
cell_format = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/CELL_FILE_FORMAT")
cell_file = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/CELL_FILE_NAME")
def cell_generator():
for line in cell_file:
line = line.strip()
if line.startswith("#"):
continue
split = line.split()
A = [float(x) for x in split[2:5]]
B = [float(x) for x in split[5:8]]
C = [float(x) for x in split[8:11]]
result = np.array([A, B, C])
yield result
result.value_iterable = cell_generator()
return result
# Multiplication factor
factor = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/CELL_FILE_NAME")
else:
# Cell given as three vectors
A = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/A")
B = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/B")
C = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/C")
A_unit = self.get_cp2k_unit("FORCE_EVAL/SUBSYS/CELL/A")
B_unit = self.get_cp2k_unit("FORCE_EVAL/SUBSYS/CELL/B")
C_unit = self.get_cp2k_unit("FORCE_EVAL/SUBSYS/CELL/C")
A = [float(x) for x in A.split()]
print A
print B
print C
print A_unit
print B_unit
print C_unit
# if A and B and C:
# cell = np.empty((3, 3))
# return
# # Cell given as three lengths and three angles
# ABC = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/ABC")
# abg = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/ALPHA_BETA_GAMMA")
# # Cell given in external file
# cell_format = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/CELL_FILE_FORMAT")
# cell_file = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/CELL_FILE_NAME")
# # Multiplication factor
# factor = self.input_tree.get_keyword("FORCE_EVAL/SUBSYS/CELL/CELL_FILE_NAME")
#===============================================================================
......
......@@ -210,6 +210,30 @@ class TestTrajectory(unittest.TestCase):
self.assertEqual(n_particles, 2)
self.assertEqual(n_dim, 3)
#===============================================================================
class TestCell(unittest.TestCase):
def test_cell_motion(self):
parser = getparser("cell/motion")
pos = parser.parse_quantity("cell")
n_conf = pos.shape[0]
n_vectors = pos.shape[1]
n_dim = pos.shape[2]
self.assertEqual(n_conf, 11)
self.assertEqual(n_vectors, 3)
self.assertEqual(n_dim, 3)
def test_cell_vectors(self):
parser = getparser("cell/vectors")
pos = parser.parse_quantity("cell")
n_conf = pos.shape[0]
n_vectors = pos.shape[1]
n_dim = pos.shape[2]
self.assertEqual(n_conf, 1)
self.assertEqual(n_vectors, 3)
self.assertEqual(n_dim, 3)
if __name__ == '__main__':
logger = logging.getLogger("cp2kparser")
logger.setLevel(logging.ERROR)
......@@ -218,10 +242,11 @@ if __name__ == '__main__':
# unittest.main()
suites = []
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestForces))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestParticleNumber))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestFunctionals))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestTrajectory))
# suites.append(unittest.TestLoader().loadTestsFromTestCase(TestForces))
# suites.append(unittest.TestLoader().loadTestsFromTestCase(TestParticleNumber))
# suites.append(unittest.TestLoader().loadTestsFromTestCase(TestFunctionals))
# suites.append(unittest.TestLoader().loadTestsFromTestCase(TestTrajectory))
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestCell))
alltests = unittest.TestSuite(suites)
unittest.TextTestRunner(verbosity=0).run(alltests)
......
......@@ -169,9 +169,7 @@ MyParser could be now used as follows:
"""
parser = MyParser(json.dumps(input_json))
parser.parse_quantity("energy_total")
parser.parse_quantity("particle_forces")
parser.parse_quantity("particle_position")
parser.parse()
```
The input JSON string is used to initialize the parser. The 'metaInfoFile'
......
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