From 2e17769d357becdb75b5b34680537df5c6352e01 Mon Sep 17 00:00:00 2001 From: Sebastiaan Huber Date: Thu, 27 Aug 2020 16:30:41 +0200 Subject: [PATCH] Fix the incorrect usage of repository interface of `aiida-core` The following illegal uses have been fixed: * `Node.open` has to be use in a context manager * `Node._get_base_folder` will soon be removed and cannot be used. --- aiida_quantumespresso/parsers/cp.py | 11 ++++---- aiida_quantumespresso/parsers/neb.py | 7 +++--- aiida_quantumespresso/parsers/parse_raw/cp.py | 25 ++++++++----------- .../parsers/parse_raw/neb.py | 17 ++++--------- 4 files changed, 25 insertions(+), 35 deletions(-) diff --git a/aiida_quantumespresso/parsers/cp.py b/aiida_quantumespresso/parsers/cp.py index 1057706a5..40b32e0b8 100644 --- a/aiida_quantumespresso/parsers/cp.py +++ b/aiida_quantumespresso/parsers/cp.py @@ -45,10 +45,10 @@ def parse(self, **kwargs): return self.exit(self.exit_codes.ERROR_MISSING_XML_FILE) # Let's pass file handlers to this function - out_dict, _raw_successful = parse_cp_raw_output( - out_folder.open(stdout_filename), out_folder.open(xml_files[0]), - out_folder.open(self.node.process_class._FILE_XML_PRINT_COUNTER_BASENAME) - ) + output_stdout = out_folder.get_object_content(stdout_filename) + output_xml = out_folder.get_object_content(xml_files[0]) + output_xml_counter = out_folder.get_object_content(self.node.process_class._FILE_XML_PRINT_COUNTER_BASENAME) + out_dict, _raw_successful = parse_cp_raw_output(output_stdout, output_xml, output_xml_counter) # parse the trajectory. Units in Angstrom, picoseconds and eV. # append everthing in the temporary dictionary raw_trajectory @@ -96,7 +96,8 @@ def parse(self, **kwargs): # =============== EVP trajectory ============================ try: - matrix = numpy.genfromtxt(out_folder.open('{}.evp'.format(self._node.process_class._PREFIX))) + with out_folder.open('{}.evp'.format(self._node.process_class._PREFIX)) as handle: + matrix = numpy.genfromtxt(handle) # there might be a different format if the matrix has one row only try: matrix.shape[1] diff --git a/aiida_quantumespresso/parsers/neb.py b/aiida_quantumespresso/parsers/neb.py index 27b321d5f..9afa0b9b9 100644 --- a/aiida_quantumespresso/parsers/neb.py +++ b/aiida_quantumespresso/parsers/neb.py @@ -60,13 +60,12 @@ def parse(self, **kwargs): # load the neb input parameters dictionary neb_input_dict = self.node.inputs.parameters.get_dict() - stdout_abspath = os.path.join(out_folder._repository._get_base_folder().abspath, filename_stdout) - # First parse the Neb output try: - neb_out_dict, iteration_data, raw_successful = parse_raw_output_neb(stdout_abspath, neb_input_dict) + stdout = out_folder.get_object_content(filename_stdout) + neb_out_dict, iteration_data, raw_successful = parse_raw_output_neb(stdout, neb_input_dict) # TODO: why do we ignore raw_successful ? - except QEOutputParsingError as exc: + except (OSError, QEOutputParsingError): return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ) for warn_type in ['warnings', 'parser_warnings']: diff --git a/aiida_quantumespresso/parsers/parse_raw/cp.py b/aiida_quantumespresso/parsers/parse_raw/cp.py index d8a5cabc7..207377600 100644 --- a/aiida_quantumespresso/parsers/parse_raw/cp.py +++ b/aiida_quantumespresso/parsers/parse_raw/cp.py @@ -149,30 +149,27 @@ def parse_cp_xml_counter_output(data): return parsed_data -def parse_cp_raw_output(out_file, xml_file=None, xml_counter_file=None): +def parse_cp_raw_output(stdout, output_xml=None, output_xml_counter=None): parser_info = get_parser_info(parser_info_template='aiida-quantumespresso parser cp.x v{}') - # analyze the xml - if xml_file is not None: - xml_data = parse_cp_xml_output(xml_file.read()) - else: + if output_xml is None: parser_info['parser_warnings'].append('Skipping the parsing of the xml file.') xml_data = {} - - # analyze the counter file, which keeps info on the steps - if xml_counter_file is not None: - xml_counter_data = parse_cp_xml_counter_output(xml_counter_file.read()) else: - xml_counter_data = {} + xml_data = parse_cp_xml_output(output_xml) - # analyze the standard output - out_lines = out_file.readlines() + # XML counter file, which keeps info on the steps + if output_xml_counter is None: + xml_counter_data = {} + else: + xml_counter_data = parse_cp_xml_counter_output(output_xml_counter) + stdout = stdout.split('\n') # understand if the job ended smoothly - job_successful = any('JOB DONE' in line for line in reversed(out_lines)) + job_successful = any('JOB DONE' in line for line in reversed(stdout)) - out_data = parse_cp_text_output(out_lines, xml_data) + out_data = parse_cp_text_output(stdout, xml_data) for key in out_data.keys(): if key in list(xml_data.keys()): diff --git a/aiida_quantumespresso/parsers/parse_raw/neb.py b/aiida_quantumespresso/parsers/parse_raw/neb.py index fbfb13304..315deff0b 100644 --- a/aiida_quantumespresso/parsers/parse_raw/neb.py +++ b/aiida_quantumespresso/parsers/parse_raw/neb.py @@ -11,10 +11,10 @@ from aiida_quantumespresso.parsers.parse_raw import convert_qe_time_to_sec -def parse_raw_output_neb(out_file, input_dict, parser_opts=None): +def parse_raw_output_neb(stdout, input_dict, parser_opts=None): """Parses the output of a neb calculation Receives in input the paths to the output file. - :param out_file: path to neb std output + :param stdout: the stdout content as a string :param input_dict: dictionary with the neb input parameters :param parser_opts: not used @@ -33,19 +33,12 @@ def parse_raw_output_neb(out_file, input_dict, parser_opts=None): job_successful = True parser_info = get_parser_info(parser_info_template='aiida-quantumespresso parser neb.x v{}') - # load NEB output file - try: - with open(out_file, 'r') as f: - out_lines = f.read() - except IOError: # non existing output file -> job crashed - raise QEOutputParsingError('Failed to open output file: {}.'.format(out_file)) - - if not out_lines: # there is an output file, but it's empty -> crash + if not stdout: # there is an output file, but it's empty -> crash job_successful = False # check if the job has finished (that doesn't mean without errors) finished_run = False - for line in out_lines.split('\n')[::-1]: + for line in stdout.split('\n')[::-1]: if 'JOB DONE' in line: finished_run = True break @@ -56,7 +49,7 @@ def parse_raw_output_neb(out_file, input_dict, parser_opts=None): # parse the text output of the neb calculation try: - out_data, iteration_data, critical_messages = parse_neb_text_output(out_lines, input_dict) + out_data, iteration_data, critical_messages = parse_neb_text_output(stdout, input_dict) except QEOutputParsingError as exc: if not finished_run: # I try to parse it as much as possible parser_info['parser_warnings'].append('Error while parsing the output file')