Skip to content

Commit

Permalink
OpengridCalculation: Simplify in/output spec
Browse files Browse the repository at this point in the history
With (aiidateam#747) the `ProjwfcParser` has no implicit requirements on
parent calculation. The code for compatibility with `ProjwfcCalculation`
is now removed.
  • Loading branch information
qiaojunfeng committed Oct 5, 2021
1 parent 02d42bb commit 6f5c587
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 56 deletions.
25 changes: 6 additions & 19 deletions aiida_quantumespresso/calculations/opengrid.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""`CalcJob` implementation for the open_grid.x code of Quantum ESPRESSO."""
from aiida.orm import RemoteData, FolderData, Dict, KpointsData, StructureData
from aiida.orm import RemoteData, FolderData, KpointsData
from aiida_quantumespresso.calculations.namelists import NamelistsCalculation


Expand All @@ -20,33 +20,20 @@ def define(cls, spec):
# yapf: disable
super().define(spec)
spec.input('parent_folder', valid_type=(RemoteData, FolderData),
help='The output folder of a completed `PwCalculation`')
# `ProjwfcParser` of `ProjwfcCalculation` requires a previous Calculation
# having an input or output structure to parse atomic orbitals.
# Here we define an optional input structure so `ProjwfcCalculation`
# could restart from an `OpengridCalculation`.
# We cannot output the structure of the parent calculation, because
# the following exception occurs for the `StructureData` node
# ValueError: node already has an incoming LinkType.CREATE link
spec.input('structure', valid_type=StructureData, required=False,
help='Optional input for a structure, can be used by a subsequent projwfc.x calculation')
# `ProjwfcParser` also requires input or output `kpoints`, and
# `output_parameters` which must has a key `number_of_spin_components`.
# Useful for a subsequent projwfc.x calculation
spec.output('output_parameters', valid_type=Dict)
help='The output folder of a completed `PwCalculation` on an irreducible Brillouin zone')
# Outputs the dimensions of the unfolded kmesh
spec.output('kpoints_mesh', valid_type=KpointsData)
# Outputs an explicit list of kpoints of the unfolded kmesh
spec.output('kpoints', valid_type=KpointsData)
spec.default_output_node = 'output_parameters'
spec.default_output_node = 'kpoints'

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',
spec.exit_code(311, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
message='The stdout output file was incomplete probably because the calculation got interrupted.')
spec.exit_code(340, 'ERROR_GENERIC_QE_ERROR',
message='Encountered a generic error message')
spec.exit_code(350, 'ERROR_UNEXPECTED_PARSER_EXCEPTION',
message='An error happened while parsing the output file')
spec.exit_code(350, 'ERROR_OUTPUT_KPOINTS_MISMATCH',
message='Mismatch between kmesh dimensions and number of kpoints')
45 changes: 16 additions & 29 deletions aiida_quantumespresso/parsers/opengrid.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
from aiida.common import NotExistent, LinkType
from aiida.orm import Dict, KpointsData, CalcJobNode
from aiida.common import NotExistent
from aiida.orm import KpointsData

from aiida_quantumespresso.parsers import QEOutputParsingError
from aiida_quantumespresso.parsers.parse_raw.base import parse_output_base
from aiida_quantumespresso.parsers.base import Parser

Expand All @@ -11,11 +10,7 @@ class OpengridParser(Parser):
"""`Parser` implementation for the `OpengridCalculation` calculation job class."""

def parse(self, **kwargs):
"""Parse the retrieved files of a completed `OpengridCalculation` into output nodes.
Two nodes that are expected are the default 'retrieved' `FolderData` node which will store the retrieved files
permanently in the repository.
"""
"""Parse the retrieved files of a completed `OpengridCalculation` into output nodes."""
try:
out_folder = self.retrieved
except NotExistent:
Expand All @@ -36,31 +31,24 @@ def parse(self, **kwargs):
elif logs.error:
return self.exit(self.exit_codes.ERROR_GENERIC_QE_ERROR)

self.parse_kpoints(out_file)

try:
parent_calc = (
self.node.inputs.parent_folder.get_incoming(node_class=CalcJobNode,
link_type=LinkType.CREATE).one().node
)
except ValueError as e:
raise QEOutputParsingError(f'Could not get parent calculation of input folder: {e}')

# We need to output additional nodes for a subsequent projwfc calculation:
# projwfc parser needs `number_of_spin_components`
try:
parent_param = parent_calc.get_outgoing(link_label_filter='output_parameters').one().node
kpoints_mesh, kpoints = self.parse_kpoints(out_file)
except ValueError:
raise QEOutputParsingError('The parent had no output_parameters! Cannot parse from this!')
nspin = parent_param.get_dict()['number_of_spin_components']
parsed_data['number_of_spin_components'] = nspin
self.out('output_parameters', Dict(dict=parsed_data))
return self.exit(self.exit_codes.ERROR_OUTPUT_KPOINTS_MISMATCH)

# Output both the dimensions and the explict list of kpoints
self.out('kpoints_mesh', kpoints_mesh)
self.out('kpoints', kpoints)

def parse_kpoints(self, out_file):
@classmethod
def parse_kpoints(cls, out_file):
"""Parse and output the dimensions and the explicit list of kpoints"""
lines = out_file.split('\n')

kpoints = []
weights = []
found_kpoints = False

for line in lines:
if 'EXX: q-point mesh:' in line:
kmesh = [int(i) for i in line.strip().split()[-3:]]
Expand All @@ -82,7 +70,6 @@ def parse_kpoints(self, out_file):
kpoints_list.set_kpoints(kpoints, cartesian=False, weights=weights)

if kmesh[0] * kmesh[1] * kmesh[2] != len(kpoints):
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE)
raise ValueError('Mismatch between kmesh dimensions and number of kpoints')

self.out('kpoints_mesh', kpoints_mesh)
self.out('kpoints', kpoints_list)
return kpoints_mesh, kpoints_list
10 changes: 2 additions & 8 deletions aiida_quantumespresso/parsers/projwfc.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,7 @@ def spin_dependent_subparser(out_info_dict):
try:
parent_kpoints = parent_calc.get_incoming(link_label_filter='kpoints').one().node
except ValueError:
try:
parent_kpoints = parent_calc.get_outgoing(link_label_filter='kpoints').one().node
except ValueError:
raise QEOutputParsingError('The parent had no input/output kpoints! Cannot parse from this!')
raise QEOutputParsingError('The parent had no input kpoints! Cannot parse from this!')
try:
if len(od['k_vect']) != len(parent_kpoints.get_kpoints()):
raise AttributeError
Expand Down Expand Up @@ -402,10 +399,7 @@ def _parse_bands_and_projections(self, out_info_dict):
try:
structure = parent_calc.get_incoming(link_label_filter='structure').one().node
except ValueError:
try:
structure = parent_calc.get_outgoing(link_label_filter='structure').one().node
except ValueError:
raise QEOutputParsingError('The parent had no input/output structure! Cannot parse from this!')
raise QEOutputParsingError('The parent had no input structure! Cannot parse from this!')
try:
nspin = parent_param.get_dict()['number_of_spin_components']
if nspin != 1:
Expand Down

0 comments on commit 6f5c587

Please sign in to comment.