Skip to content

Commit

Permalink
NamelistsCalculation: make inputs 'parameters' and 'settings' optio…
Browse files Browse the repository at this point in the history
…nal (aiidateam#277)

Also add a CLI launcher for `DosCalculation` calculation plugin
  • Loading branch information
borellim authored and sphuber committed May 7, 2019
1 parent 7e79a7b commit 3d68cc8
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 13 deletions.
28 changes: 16 additions & 12 deletions aiida_quantumespresso/calculations/namelists.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def define(cls, spec):
spec.input('metadata.options.input_filename', valid_type=six.string_types, default=cls._DEFAULT_INPUT_FILE, non_db=True)
spec.input('metadata.options.output_filename', valid_type=six.string_types, default=cls._DEFAULT_OUTPUT_FILE, non_db=True)
spec.input('metadata.options.parser_name', valid_type=six.string_types, required=False, non_db=True)
spec.input('parameters', valid_type=Dict, help='Use a node that specifies the input parameters for the namelists')
spec.input('settings', valid_type=Dict, required=False, default=Dict(dict={}), help='Use an additional node for special settings')
spec.input('parameters', valid_type=Dict, required=False, help='Use a node that specifies the input parameters for the namelists')
spec.input('settings', valid_type=Dict, required=False, help='Use an additional node for special settings')
spec.input('parent_folder', valid_type=(RemoteData, FolderData, SinglefileData), required=False, help='Use a local or remote folder as parent folder (for restarts and similar)')

def _get_following_text(self, settings_dict):
Expand All @@ -85,9 +85,12 @@ def prepare_for_submission(self, folder):
remote_copy_list = []

# Settings converted to uppercase
settings_dict = _uppercase_dict(self.inputs.settings.get_dict(),
dict_name='settings')

if 'settings' in self.inputs:
settings_dict = _uppercase_dict(self.inputs.settings.get_dict(),
dict_name='settings')
else:
settings_dict = {}

following_text = self._get_following_text(settings_dict)

##############################
Expand All @@ -97,10 +100,13 @@ def prepare_for_submission(self, folder):
# I put the first-level keys as uppercase (i.e., namelist and card names)
# and the second-level keys as lowercase
# (deeper levels are unchanged)
input_params = _uppercase_dict(self.inputs.parameters.get_dict(),
dict_name='parameters')
input_params = {k: _lowercase_dict(v, dict_name=k)
for k, v in six.iteritems(input_params)}
if 'parameters' in self.inputs:
input_params = _uppercase_dict(self.inputs.parameters.get_dict(),
dict_name='parameters')
input_params = {k: _lowercase_dict(v, dict_name=k)
for k, v in six.iteritems(input_params)}
else:
input_params = {}

# set default values. NOTE: this is different from PW/CP
for blocked in self._blocked_keywords:
Expand All @@ -113,9 +119,7 @@ def prepare_for_submission(self, folder):
raise InputValidationError(
"You cannot specify explicitly the '{}' key in the '{}' "
"namelist.".format(key, namelist))

# set to a default
if namelist not in input_params:
else:
input_params[namelist] = {}
input_params[namelist][key] = value

Expand Down
57 changes: 57 additions & 0 deletions aiida_quantumespresso/cli/calculations/dos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""Command line scripts to launch a `PwCalculation` for testing and demonstration purposes."""
from __future__ import absolute_import
import click

from aiida.orm import RemoteData
from aiida.cmdline.params import options, types
from aiida.cmdline.utils import decorators

from aiida_quantumespresso.cli.utils import options as options_qe


@click.command()
@options.CODE(required=True, type=types.CodeParamType(entry_point='quantumespresso.dos'))
@options.CALCULATION(required=True)
@options_qe.MAX_NUM_MACHINES()
@options_qe.MAX_WALLCLOCK_SECONDS()
@options_qe.WITH_MPI()
@options_qe.DAEMON()
@decorators.with_dbenv()
def cli(code, calculation, max_num_machines, max_wallclock_seconds, with_mpi, daemon):
"""Run a DosCalculation."""
from aiida.engine import launch
from aiida.plugins import CalculationFactory
from aiida_quantumespresso.utils.resources import get_default_options

DosCalculation = CalculationFactory('quantumespresso.dos') # pylint: disable=invalid-name

# Check that the parent calculation node comes from quantumespresso.pw.
# I cannot move this check into the option declaration, because CalcJobNode is not subclassed by the specific
# calculation plugins (only Process is), and there is no feature yet to filter by the associated process_type.
expected_process_type = 'aiida.calculations:quantumespresso.pw'
if calculation.process_type != expected_process_type:
raise click.BadParameter('The input calculation node has a process_type: {}; should be {}'.format(
calculation.process_type, expected_process_type))
parent_folder = calculation.get_outgoing(node_class=RemoteData, link_label_filter='remote_folder').one().node

inputs = {
'code': code,
'parent_folder': parent_folder,
'metadata': {
'options': get_default_options(max_num_machines, max_wallclock_seconds, with_mpi),
}
}

if daemon:
new_calc = launch.submit(DosCalculation, **inputs)
click.echo('Submitted {}<{}> to the daemon'.format(DosCalculation.__name__, new_calc.pk))
else:
click.echo('Running a dos.x calculation from parent {}<{}>... '.format(calculation.__class__.__name__,
calculation.pk))
_, new_calc = launch.run_get_node(DosCalculation, **inputs)
click.echo('DosCalculation<{}> terminated with state: {}'.format(new_calc.pk, new_calc.process_state))
click.echo('\n{link:25s} {node}'.format(link='Output link', node='Node pk and type'))
click.echo('{s}'.format(s='-' * 60))
for triple in sorted(new_calc.get_outgoing().all(), key=lambda triple: triple.link_label):
click.echo('{:25s} {}<{}> '.format(triple.link_label, triple.node.__class__.__name__, triple.node.pk))
1 change: 0 additions & 1 deletion aiida_quantumespresso/cli/calculations/pw/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def cli(code, structure, pseudo_family, kpoints_mesh, ecutwfc, ecutrho, hubbard_
'pseudos': get_pseudos_from_structure(structure, pseudo_family),
'kpoints': kpoints_mesh,
'parameters': Dict(dict=parameters),
'settings': Dict(dict={}),
'metadata': {
'options': get_default_options(max_num_machines, max_wallclock_seconds, with_mpi),
}
Expand Down

0 comments on commit 3d68cc8

Please sign in to comment.