diff --git a/parser/parser-dl_poly/dlPolyParser.py b/parser/parser-dl_poly/dlPolyParser.py index 017069c17ab3c8201aca815216237f1a6d0a4668..3e4c0a0b3275232ea9094d463ea3f119c2fee03e 100644 --- a/parser/parser-dl_poly/dlPolyParser.py +++ b/parser/parser-dl_poly/dlPolyParser.py @@ -9,7 +9,7 @@ from nomadcore.local_meta_info import loadJsonFile, InfoKindEl from nomadcore.parser_backend import JsonParseEventsWriterBackend from contextlib import contextmanager -from libDL_POLYParser import * +from libDlPolyParser import * try: from momo import osio, endl, flush @@ -39,48 +39,99 @@ def open_section(p, name): yield p.closeSection(name, gid) +def push(jbe, terminal, key1, fct=lambda x: x.As(), key2=None): + if key2 == None: key2 = key1 + value = fct(terminal[key2]) + jbe.addValue(key1, value) + return value def parse(output_file_name): - p = JsonParseEventsWriterBackend(meta_info_env) - o = open_section - p.startedParsingSession(output_file_name, parser_info) + jbe = JsonParseEventsWriterBackend(meta_info_env) + jbe.startedParsingSession(output_file_name, parser_info) - # PARSE CONTROLS + # PARSE CONTROLS ... ctrl_file_name = 'CONTROL' terminal_ctrls = DlPolyControls(osio) - terminal_ctrls.ParseControls(ctrl_file_name) - - # PARSE OUTPUT / TOPOLOGY + terminal_ctrls.ParseControls(ctrl_file_name) + # PARSE OUTPUT / TOPOLOGY ... output_file_name = 'OUTPUT' terminal = DlPolyParser(osio) - terminal.ParseOutput(output_file_name) - - # PARSE TRAJECTORY + terminal.ParseOutput(output_file_name) + # PARSE TRAJECTORY ... cfg_file_name = 'CONFIG' terminal_trj = DlPolyConfig(osio) terminal_trj.ParseConfig(cfg_file_name) - - # SUMMARIZE KEY-TABLE DEFAULTS + # SUMMARIZE KEY-TABLE DEFAULTS ... terminal.SummarizeKeyDefaults() terminal.topology.SummarizeKeyDefaults() terminal_ctrls.SummarizeKeyDefaults() terminal_trj.SummarizeKeyDefaults() + # ABBREVIATE ... + ctr = terminal_ctrls + out = terminal + top = terminal.topology + trj = terminal_trj - osio.okquit() - - with o(p, 'section_run'): - p.addValue('program_name', 'DL_POLY') - - with o(p, 'section_topology'): - pass - - with o(p, 'section_sampling_method'): + ofs = open('keys.log', 'w') + terminals = [ctr, out, top, trj] + for t in terminals: + keys = sorted(t.data.keys()) + for key in keys: + ofs.write('[%s] %s\n' % (t.logtag, key)) + ofs.write('\n') + ofs.close() + + # PUSH TO BACKEND + with open_section(jbe, 'section_run'): + push(jbe, out, 'program_name') + push(jbe, out, 'program_version') + push(jbe, out, 'program_info', key2='program_version_date') + + with open_section(jbe, 'section_topology'): + push(jbe, top, 'number_of_topology_molecules', lambda s: s.As(int)) + push(jbe, top, 'number_of_topology_atoms', lambda s: s.As(int)) + # Molecule types + for mol in top.molecules: + with open_section(jbe, 'section_molecule_type'): + push(jbe, mol, 'molecule_type_name') + push(jbe, mol, 'number_of_atoms_in_molecule', lambda s: s.As(int)) + # TODO settings_atom_... is abstract type => set atom_in_molecule_charge via list, + # TODO same for atom_in_molecule_name + # TODO atom_to_molecule, molecule_to_molecule_type, atom_in_molecule_to_atom_type_ref + for atom in mol.atoms: + with open_section(jbe, 'settings_atom_in_molecule'): + push(jbe, atom, 'atom_in_molecule_charge', lambda s: s.As(float), 'atom_charge') + push(jbe, atom, 'atom_in_molecule_name', lambda s: s.As(), 'atom_name') + # Atom types + for mol in top.molecules: + for atom in mol.atoms: + with open_section(jbe, 'section_atom_type'): + push(jbe, atom, 'atom_type_name', lambda s: s.As(), 'atom_name') + push(jbe, atom, 'atom_type_mass', lambda s: s.As(float), 'atom_mass') + push(jbe, atom, 'atom_type_charge', lambda s: s.As(float), 'atom_charge') + + + with open_section(jbe, 'section_sampling_method'): + # Ensemble + ensemble = push(jbe, out, 'ensemble_type', lambda s: s.As().split()[0].upper()) + # Method + push(jbe, out, 'sampling_method') + push(jbe, out, 'integrator_type') + push(jbe, out, 'integrator_dt', lambda s: s.As(float)) + push(jbe, out, 'number_of_steps_requested', lambda s: s.As(int)) + # Coupling + if 'T' in ensemble: + push(jbe, out, 'thermostat_target_temperature', lambda s: s.As(float)) + push(jbe, out, 'thermostat_tau', lambda s: s.As(float)) + if 'P' in ensemble: + push(jbe, out, 'barostat_target_pressure', lambda s: s.As(float)) + push(jbe, out, 'barostat_tau', lambda s: s.As(float)) pass - with o(p, 'section_frame_sequence'): + with open_section(jbe, 'section_frame_sequence'): pass - p.finishedParsingSession("ParseSuccess", None) + jbe.finishedParsingSession("ParseSuccess", None) return if __name__ == '__main__': diff --git a/parser/parser-dl_poly/libDlPolyParser.py b/parser/parser-dl_poly/libDlPolyParser.py index 9eefc69b808c61a2d182ef463c549123b61a9d0d..2e0db546f47156707a3200eb11b5b28e7f122e4c 100644 --- a/parser/parser-dl_poly/libDlPolyParser.py +++ b/parser/parser-dl_poly/libDlPolyParser.py @@ -2,19 +2,26 @@ import os import sys import re +# TODO Distinguish: number_of_steps vs number_of_steps_equilibration +# TODO Check units and install conversions +# TODO - Pressure +# TODO Check sampling_method + + + # ================= # TRANSLATION RULES # ================= KEY_TRANSFORM_SIM_CTRL = { -'simulation_temperature_k' : 'thermostat_T', -'simulation_pressure_katms' : 'barostat_P', -'integration' : 'integrator', -'ensemble' : None, +'simulation_temperature_k' : 'thermostat_target_temperature', +'simulation_pressure_katms' : 'barostat_target_pressure', +'integration' : 'integrator_type', +'ensemble' : 'ensemble_type', 'thermostat_relaxation_time_ps' : 'thermostat_tau', 'barostat_relaxation_time_ps' : 'barostat_tau', -'selected_number_of_timesteps' : 'n_steps', -'equilibration_period_steps' : 'n_steps_equ', +'selected_number_of_timesteps' : 'number_of_steps_requested', +'equilibration_period_steps' : 'number_of_steps_equil_requested', 'temperature_scaling_on_during' : None, 'temperature_scaling_interval' : None, 'equilibration_included_in_overall' : None, @@ -29,7 +36,7 @@ KEY_TRANSFORM_SIM_CTRL = { 'extended_coulombic_exclusion' : None, 'cutoff_padding_reset_to_angs' : None, 'vdw_cutoff_reset_to_angs' : None, -'fixed_simulation_timestep_ps' : None, +'fixed_simulation_timestep_ps' : 'integrator_dt', 'data_dumping_interval_steps' : None, 'allocated_job_run_time_s' : None, 'allocated_job_close_time_s' : None @@ -43,7 +50,7 @@ KEY_TRANSFORM_SYS_SPEC = { KEY_TRANSFORM_MOL_GLOBAL = { 'molecular_species_type' : 'molecule_type_id', 'name_of_species' : 'molecule_type_name', -'number_of_molecules' : 'n_instances_molecule_type' +'number_of_molecules' : 'number_of_molecules' } KEY_RULES_CONTROLS = { @@ -347,10 +354,12 @@ class DlPolyParser(object): self.log << self.log.mg << "Start simulation method ..." << self.log.endl ifs = FileStream(output_file) + self.Set('program_name', 'DL_POLY') + self.Set('sampling_method', 'molecular_dynamics') # HEADER & NODE STRUCTURE ln = ifs.SkipTo('** DL_POLY **') - self.SearchMapKeys('version:\s*(\d+.\d+)\s*/\s*(\w+\s*\d+)', ifs.ln(), ['version', 'version_date']) + self.SearchMapKeys('version:\s*(\d+.\d+)\s*/\s*(\w+\s*\d+)', ifs.ln(), ['program_version', 'program_version_date']) self.SearchMapKeys('execution on\s*(\d+)\s*node', ifs.ln(), ['n_nodes']) ln = ifs.SkipTo('node/domain decomposition') self.Set('domain_decomposition', map(int, ln.split()[-3:])) @@ -487,7 +496,18 @@ class DlPolyTopology(DlPolyParser): self.molecules = [] for block_mol in block_mols: if self.log: self.log << self.log.mg << "Start molecule ..." << self.log.endl - new_mol = DlPolyMolecule(block_mol, self) + new_mol = DlPolyMolecule(block_mol, self) + self.molecules.append(new_mol) + + n_atoms_total = 0 + n_molecules_total = 0 + for mol in self.molecules: + n_mol = mol['number_of_molecules'].As(int) + n_atoms = mol['number_of_atoms_in_molecule'].As(int) + n_atoms_total += n_mol*n_atoms + n_molecules_total += n_mol + self.Set('number_of_topology_atoms', n_atoms_total) + self.Set('number_of_topology_molecules', n_molecules_total) return @@ -526,7 +546,7 @@ class DlPolyMolecule(DlPolyParser): if self.log: self.log << self.log.mg << "Start atoms ..." << self.log.endl block = blocks[expr_atoms][0] n_atoms = int(block.ln().split()[-1]) - self.Set('n_atoms_in_molecule', n_atoms) + self.Set('number_of_atoms_in_molecule', n_atoms) assert 'atomic characteristics' in block.ln() # Determine atom properties atom_property_labels = block.ln().split()