Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsers: remove explicit check for the retrieved folder's existence #580

Merged
merged 1 commit into from
Oct 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/cp.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ def define(cls, spec):
spec.output('output_parameters', valid_type=orm.Dict)
spec.default_output_node = 'output_parameters'

spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(301, 'ERROR_NO_RETRIEVED_TEMPORARY_FOLDER',
message='The retrieved temporary folder could not be accessed.')
spec.exit_code(303, 'ERROR_MISSING_XML_FILE',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ def define(cls, spec):
spec.output('output_parameters', valid_type=orm.Dict)
spec.output('output_dos', valid_type=orm.XyData)
spec.default_output_node = 'output_parameters'
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
message='The stdout output file could not be read.')
spec.exit_code(312, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/matdyn.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ def define(cls, spec):
spec.output('output_parameters', valid_type=orm.Dict)
spec.output('output_phonon_bands', valid_type=orm.BandsData)
spec.default_output_node = 'output_parameters'
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
message='The stdout output file could not be read.')
spec.exit_code(312, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/neb.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ def define(cls, spec):
spec.output('output_mep', valid_type=orm.ArrayData,
help='The original and interpolated energy profiles along the minimum-energy path (mep)')
spec.default_output_node = 'output_parameters'
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(303, 'ERROR_MISSING_XML_FILE',
message='The required XML file is not present in the retrieved folder.')
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/ph.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ def define(cls, spec):
spec.default_output_node = 'output_parameters'

# Unrecoverable errors: required retrieved files could not be read, parsed or are otherwise incomplete
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(302, 'ERROR_OUTPUT_STDOUT_MISSING',
message='The retrieved folder did not contain the required stdout output file.')
spec.exit_code(305, 'ERROR_OUTPUT_FILES',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/pp.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ def define(cls, spec):
spec.default_output_node = 'output_parameters'

# Standard exceptions
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(301, 'ERROR_NO_RETRIEVED_TEMPORARY_FOLDER',
message='The retrieved temporary folder could not be accessed.')
spec.exit_code(302, 'ERROR_OUTPUT_STDOUT_MISSING',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/projwfc.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ def define(cls, spec):
spec.output('projections', valid_type=ProjectionData, required=False)
spec.output('bands', valid_type=BandsData, required=False)
spec.default_output_node = 'output_parameters'
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
message='The stdout output file could not be read.')
spec.exit_code(312, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/pw.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ def define(cls, spec):
spec.default_output_node = 'output_parameters'

# Unrecoverable errors: required retrieved files could not be read, parsed or are otherwise incomplete
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(301, 'ERROR_NO_RETRIEVED_TEMPORARY_FOLDER',
message='The retrieved temporary folder could not be accessed.')
spec.exit_code(302, 'ERROR_OUTPUT_STDOUT_MISSING',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/pw2gw.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ def define(cls, spec):
spec.output('eps', valid_type=orm.ArrayData,
help='The `eps` output node containing 5 arrays `energy`, `epsX`, `epsY`, `epsZ`, `epsTOT`')

spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(302, 'ERROR_OUTPUT_STDOUT_MISSING',
message='The retrieved folder did not contain the required stdout output file.')
spec.exit_code(305, 'ERROR_OUTPUT_FILES',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/pw2wannier90.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ def define(cls, spec):
help='The output folder of a pw.x calculation')
spec.output('output_parameters', valid_type=Dict)
spec.default_output_node = 'output_parameters'
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
message='The stdout output file could not be read.')
spec.exit_code(312, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
Expand Down
2 changes: 0 additions & 2 deletions aiida_quantumespresso/calculations/q2r.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ def define(cls, spec):
super().define(spec)
spec.input('parent_folder', valid_type=(orm.RemoteData, orm.FolderData), required=True)
spec.output('force_constants', valid_type=ForceConstantsData)
spec.exit_code(300, 'ERROR_NO_RETRIEVED_FOLDER',
message='The retrieved folder data node could not be accessed.')
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
message='The stdout output file could not be read.')
spec.exit_code(312, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
Expand Down
22 changes: 9 additions & 13 deletions aiida_quantumespresso/parsers/cp.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
from distutils.version import LooseVersion

import numpy
from aiida.common import NotExistent
from aiida.orm import Dict, TrajectoryData

from aiida.orm import Dict, TrajectoryData
from qe_tools import CONSTANTS

from aiida_quantumespresso.parsers.parse_raw.cp import parse_cp_raw_output, parse_cp_traj_stanzas
from .base import Parser

Expand All @@ -18,13 +17,10 @@ def parse(self, **kwargs):

Does all the logic here.
"""
try:
out_folder = self.retrieved
except NotExistent:
return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)
retrieved = self.retrieved

# check what is inside the folder
list_of_files = out_folder._repository.list_object_names()
list_of_files = retrieved._repository.list_object_names()

# options.metadata become attributes like this:
stdout_filename = self.node.get_attribute('output_filename')
Expand All @@ -44,9 +40,9 @@ def parse(self, **kwargs):
# TODO: Add an error for this counter
return self.exit(self.exit_codes.ERROR_MISSING_XML_FILE)

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)
output_stdout = retrieved.get_object_content(stdout_filename)
output_xml = retrieved.get_object_content(xml_files[0])
output_xml_counter = retrieved.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.
Expand Down Expand Up @@ -75,7 +71,7 @@ def parse(self, **kwargs):

for name, extension, scale, elements in trajectories:
try:
with out_folder.open(f'{self.node.process_class._PREFIX}.{extension}') as datafile:
with retrieved.open(f'{self.node.process_class._PREFIX}.{extension}') as datafile:
data = [l.split() for l in datafile]
# POSITIONS stored in angstrom
traj_data = parse_cp_traj_stanzas(
Expand All @@ -96,7 +92,7 @@ def parse(self, **kwargs):

# =============== EVP trajectory ============================
try:
with out_folder.open(f'{self._node.process_class._PREFIX}.evp') as handle:
with retrieved.open(f'{self._node.process_class._PREFIX}.evp') as handle:
matrix = numpy.genfromtxt(handle)
# there might be a different format if the matrix has one row only
try:
Expand Down
10 changes: 3 additions & 7 deletions aiida_quantumespresso/parsers/dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import numpy as np

from aiida.orm import Dict, XyData
from aiida.common import NotExistent

from aiida_quantumespresso.parsers import QEOutputParsingError
from aiida_quantumespresso.parsers.parse_raw.base import parse_output_base
Expand All @@ -17,15 +16,12 @@ def parse(self, **kwargs):

Retrieves dos output, and some basic information from the out_file, such as warnings and wall_time
"""
try:
out_folder = self.retrieved
except NotExistent:
return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)
retrieved = self.retrieved

# Read standard out
try:
filename_stdout = self.node.get_option('output_filename') # or get_attribute(), but this is clearer
with out_folder.open(filename_stdout, 'r') as fil:
with retrieved.open(filename_stdout, 'r') as fil:
out_file = fil.readlines()
except OSError:
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)
Expand All @@ -41,7 +37,7 @@ def parse(self, **kwargs):

# check that the dos file is present, if it is, read it
try:
with out_folder.open(self.node.process_class._DOS_FILENAME, 'r') as fil:
with retrieved.open(self.node.process_class._DOS_FILENAME, 'r') as fil:
dos_file = fil.readlines()
except OSError:
return self.exit(self.exit_codes.ERROR_READING_DOS_FILE)
Expand Down
15 changes: 5 additions & 10 deletions aiida_quantumespresso/parsers/matdyn.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from aiida import orm
from aiida.common import exceptions
from qe_tools import CONSTANTS

from aiida_quantumespresso.calculations.matdyn import MatdynCalculation
Expand All @@ -12,21 +11,17 @@ class MatdynParser(Parser):

def parse(self, **kwargs):
"""Parse the retrieved files from a `MatdynCalculation`."""
try:
output_folder = self.retrieved
except exceptions.NotExistent:
return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)

retrieved = self.retrieved
filename_stdout = self.node.get_option('output_filename')
filename_frequencies = MatdynCalculation._PHONON_FREQUENCIES_NAME

if filename_stdout not in output_folder.list_object_names():
if filename_stdout not in retrieved.list_object_names():
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

if 'JOB DONE' not in output_folder.get_object_content(filename_stdout):
if 'JOB DONE' not in retrieved.get_object_content(filename_stdout):
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE)

if filename_frequencies not in output_folder.list_object_names():
if filename_frequencies not in retrieved.list_object_names():
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

# Extract the kpoints from the input data and create the `KpointsData` for the `BandsData`
Expand All @@ -38,7 +33,7 @@ def parse(self, **kwargs):
kpoints_for_bands = orm.KpointsData()
kpoints_for_bands.set_kpoints(kpoints)

parsed_data = parse_raw_matdyn_phonon_file(output_folder.get_object_content(filename_frequencies))
parsed_data = parse_raw_matdyn_phonon_file(retrieved.get_object_content(filename_frequencies))

try:
num_kpoints = parsed_data.pop('num_kpoints')
Expand Down
19 changes: 7 additions & 12 deletions aiida_quantumespresso/parsers/neb.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,8 @@ def parse(self, **kwargs):

PREFIX = self.node.process_class._PREFIX

# Check that the retrieved folder is there
try:
out_folder = self.retrieved
except NotExistent:
return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)

list_of_files = out_folder.list_object_names() # Note: this includes folders, but not the files they contain.
retrieved = self.retrieved
list_of_files = retrieved.list_object_names() # Note: this includes folders, but not the files they contain.

# The stdout is required for parsing
filename_stdout = self.node.get_attribute('output_filename')
Expand All @@ -62,7 +57,7 @@ def parse(self, **kwargs):

# First parse the Neb output
try:
stdout = out_folder.get_object_content(filename_stdout)
stdout = retrieved.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 (OSError, QEOutputParsingError):
Expand Down Expand Up @@ -99,7 +94,7 @@ def parse(self, **kwargs):
if xml_filename in retrieved_files:
xml_file_path = os.path.join(relative_output_folder, xml_filename)
try:
with out_folder.open(xml_file_path) as xml_file:
with retrieved.open(xml_file_path) as xml_file:
parsed_data_xml, logs_xml = parse_pw_xml(xml_file, None)
except IOError:
return self.exit(self.exit_codes.ERROR_OUTPUT_XML_READ)
Expand All @@ -120,7 +115,7 @@ def parse(self, **kwargs):
# look for pw output and parse it
pw_out_file = os.path.join(f'{PREFIX}_{i + 1}', 'PW.out')
try:
with out_folder.open(pw_out_file, 'r') as f:
with retrieved.open(pw_out_file, 'r') as f:
pw_out_text = f.read() # Note: read() and not readlines()
except IOError:
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)
Expand Down Expand Up @@ -192,15 +187,15 @@ def parse(self, **kwargs):
# Load the original and interpolated energy profile along the minimum-energy path (mep)
try:
filename = PREFIX + '.dat'
with out_folder.open(filename, 'r') as handle:
with retrieved.open(filename, 'r') as handle:
mep = numpy.loadtxt(handle)
except Exception:
self.logger.warning(f'could not open expected output file `{filename}`.')
mep = numpy.array([[]])

try:
filename = PREFIX + '.int'
with out_folder.open(filename, 'r') as handle:
with retrieved.open(filename, 'r') as handle:
interp_mep = numpy.loadtxt(handle)
except Exception:
self.logger.warning(f'could not open expected output file `{filename}`.')
Expand Down
16 changes: 6 additions & 10 deletions aiida_quantumespresso/parsers/ph.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import traceback

from aiida import orm
from aiida.common import exceptions

from aiida_quantumespresso.calculations.ph import PhCalculation
from aiida_quantumespresso.parsers.parse_raw.ph import parse_raw_ph_output as parse_stdout
Expand All @@ -17,25 +16,22 @@ class PhParser(Parser):

def parse(self, **kwargs):
"""Parse the retrieved files from a `PhCalculation`."""
try:
self.retrieved
except exceptions.NotExistent:
return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)
retrieved = self.retrieved

# The stdout is required for parsing
filename_stdout = self.node.get_attribute('output_filename')
filename_tensor = PhCalculation._OUTPUT_XML_TENSOR_FILE_NAME

if filename_stdout not in self.retrieved.list_object_names():
if filename_stdout not in retrieved.list_object_names():
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_MISSING)

try:
stdout = self.retrieved.get_object_content(filename_stdout)
stdout = retrieved.get_object_content(filename_stdout)
except (IOError, OSError):
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

try:
tensor_file = self.retrieved.get_object_content(filename_tensor)
tensor_file = retrieved.get_object_content(filename_tensor)
except (IOError, OSError):
tensor_file = None

Expand All @@ -45,11 +41,11 @@ def parse(self, **kwargs):
dynmat_prefix = os.path.split(PhCalculation._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.list_object_names(dynmat_folder), key=natural_sort):
for filename in sorted(retrieved.list_object_names(dynmat_folder), key=natural_sort):
if not filename.startswith(dynmat_prefix) or filename.endswith('.freq'):
continue

dynmat_files.append(self.retrieved.get_object_content(os.path.join(dynmat_folder, filename)))
dynmat_files.append(retrieved.get_object_content(os.path.join(dynmat_folder, filename)))

try:
parsed_data, logs = parse_stdout(stdout, tensor_file, dynmat_files)
Expand Down
14 changes: 5 additions & 9 deletions aiida_quantumespresso/parsers/pp.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ def parse(self, **kwargs):
"""
Parse raw files retrieved from remote dir
"""
try:
self.retrieved
except exceptions.NotExistent:
return self.exit_codes.ERROR_NO_RETRIEVED_FOLDER

retrieved = self.retrieved
retrieve_temporary_list = self.node.get_attribute('retrieve_temporary_list', None)
filename_stdout = self.node.get_option('output_filename')

Expand All @@ -62,11 +58,11 @@ def parse(self, **kwargs):
return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_TEMPORARY_FOLDER)

# The stdout is required for parsing
if filename_stdout not in self.retrieved.list_object_names():
if filename_stdout not in retrieved.list_object_names():
return self.exit_codes.ERROR_OUTPUT_STDOUT_MISSING

try:
stdout_raw = self.retrieved.get_object_content(filename_stdout)
stdout_raw = retrieved.get_object_content(filename_stdout)
except (IOError, OSError):
return self.exit_codes.ERROR_OUTPUT_STDOUT_READ

Expand All @@ -89,8 +85,8 @@ def parse(self, **kwargs):
filenames = os.listdir(retrieved_temporary_folder)
file_opener = lambda filename: open(os.path.join(retrieved_temporary_folder, filename))
else:
filenames = self.retrieved.list_object_names()
file_opener = self.retrieved.open
filenames = retrieved.list_object_names()
file_opener = retrieved.open

for filename in filenames:
if filename.endswith(filename_suffix):
Expand Down
Loading