Source code for aiida_quantumespresso.parsers.ph

# -*- coding: utf-8 -*-
"""`Parser` implementation for the `PhCalculation` calculation job class."""
import os
import re

from aiida import orm

from aiida_quantumespresso.calculations.ph import PhCalculation
from aiida_quantumespresso.parsers.parse_raw.ph import parse_raw_ph_output
from aiida_quantumespresso.utils.mapping import get_logging_container

from .base import BaseParser


[docs]class PhParser(BaseParser): """``Parser`` implementation for the ``PhCalculation`` calculation job class."""
[docs] class_error_map = { 'No convergence has been achieved': 'ERROR_CONVERGENCE_NOT_REACHED', 'problems computing cholesky': 'ERROR_COMPUTING_CHOLESKY', 'FFT grid incompatible with symmetry': 'ERROR_INCOMPATIBLE_FFT_GRID', 'wrong representation': 'ERROR_WRONG_REPRESENTATION', }
[docs] def parse(self, **kwargs): """Parse the retrieved files from a ``PhCalculation`` into output nodes.""" logs = get_logging_container() stdout, parsed_data, logs = self.parse_stdout_from_retrieved(logs) # If the scheduler detected OOW, simply keep that exit code by not returning anything more specific. if self.node.exit_status == PhCalculation.exit_codes.ERROR_SCHEDULER_OUT_OF_WALLTIME: return base_exit_code = self.check_base_errors(logs) if base_exit_code: return self.exit(base_exit_code, logs) filename_tensor = self.node.process_class._OUTPUT_XML_TENSOR_FILE_NAME try: with self.retrieved.base.repository.open(filename_tensor, 'r') as handle: tensor_file = handle.read() except OSError: tensor_file = None # Look for dynamical matrices dynmat_files = [] dynmat_folder = self.node.process_class._FOLDER_DYNAMICAL_MATRIX dynmat_prefix = os.path.split(self.node.process_class._OUTPUT_DYNAMICAL_MATRIX_PREFIX)[1] natural_sort = lambda string: [int(c) if c.isdigit() else c.lower() for c in re.split(r'(\d+)', string)] for filename in sorted(self.retrieved.base.repository.list_object_names(dynmat_folder), key=natural_sort): if not filename.startswith(dynmat_prefix) or filename.endswith('.freq'): continue dynmat_files.append(self.retrieved.base.repository.get_object_content(os.path.join(dynmat_folder, filename))) parsed_ph_data, logs = parse_raw_ph_output(stdout, logs, tensor_file, dynmat_files) parsed_data.update(parsed_ph_data) self.out('output_parameters', orm.Dict(parsed_data)) for exit_code in list(self.get_error_map().values()) + ['ERROR_OUTPUT_STDOUT_INCOMPLETE']: if exit_code in logs.error: return self.exit(self.exit_codes.get(exit_code), logs) return self.exit(logs=logs)