# -*- coding: utf-8 -*-
"""Classes and methods for running xspectra.x with AiiDA."""
import os
from aiida import orm
from aiida.common import exceptions
from aiida.orm import Dict, SinglefileData, XyData
from aiida.plugins import DataFactory
from aiida_quantumespresso.calculations.namelists import NamelistsCalculation
[docs]KpointsData = DataFactory('core.array.kpoints')
[docs]class XspectraCalculation(NamelistsCalculation):
"""CalcJob implementation for the xspectra.x code of Quantum ESPRESSO."""
[docs] _Plotcore_FILENAME = 'stdout'
[docs] _Spectrum_FILENAME = 'xanes.dat'
[docs] _XSPECTRA_SAVE_FILE = 'xanes.sav'
[docs] _XSPECTRA_GAMMA_FILE = 'gamma.dat'
[docs] _default_namelists = ['INPUT_XSPECTRA', 'PLOT', 'PSEUDOS', 'CUT_OCC']
[docs] _blocked_keywords = [('INPUT_XSPECTRA', 'outdir', NamelistsCalculation._OUTPUT_SUBFOLDER),
('INPUT_XSPECTRA', 'prefix', NamelistsCalculation._PREFIX),
('INPUT_XSPECTRA', 'x_save_file', _XSPECTRA_SAVE_FILE),
('PLOT', 'gamma_file', _XSPECTRA_GAMMA_FILE), ('PSEUDOS', 'filecore', _Plotcore_FILENAME)]
[docs] _internal_retrieve_list = [_Spectrum_FILENAME]
[docs] _retrieve_singlefile_list = []
[docs] _retrieve_temporary_list = []
[docs] _default_parser = 'quantumespresso.xspectra'
@classmethod
[docs] def define(cls, spec):
"""Define the process specification."""
super().define(spec)
spec.input('parent_folder', valid_type=orm.RemoteData, required=True)
spec.input(
'core_wfc_data',
valid_type=SinglefileData,
required=True,
help='Core wavefunction data, generated by the upf2plotcore.sh utility'
)
spec.input(
'kpoints',
valid_type=KpointsData,
required=True,
help='The K-point sampling to be used for the XSpectra calculation'
)
spec.input(
'gamma_file',
valid_type=SinglefileData,
required=False,
help='An optional file containing the data for the broadening function used when'
' `gamma_mode=file`'
)
spec.output('output_parameters', valid_type=Dict)
spec.output('spectra', valid_type=XyData)
spec.default_output_node = 'output_parameters'
spec.exit_code(
313,
'ERROR_OUTPUT_ABSORBING_SPECIES_WRONG',
message='xiabs was set incorrectly, check and ensure that the index value correctly refers '
'to the atomic species containing the core-hole (where the index starts from 1).'
)
spec.exit_code(
314,
'ERROR_OUTPUT_ABSORBING_SPECIES_ZERO',
message='xiabs was either set to 0 or less, or was greater than ntyp.'
)
spec.exit_code(
400,
'ERROR_OUT_OF_WALLTIME',
message='The time limit set for the calculation was exceeded, and the job wrote a save file '
'before exiting.'
)
spec.exit_code(
330,
'ERROR_READING_SPECTRUM_FILE',
message='The xspectra output file could not be read from the retrieved folder.'
)
spec.exit_code(
331,
'ERROR_READING_SPECTRUM_FILE_DATA',
message='The spectrum data file could not be read using NumPy genfromtxt'
)
[docs] def prepare_for_submission(self, folder):
"""Override the inherited method to add the core wavefunction data file to the local_copy_list."""
calcinfo = super().prepare_for_submission(folder)
# append the core wavefunction data node to the copy list
core_file = self.inputs.core_wfc_data
core_file_info = (core_file.uuid, core_file.filename, core_file.filename)
calcinfo.local_copy_list.append(core_file_info)
# if included as an input, append the gamma file node to the copy list
if 'gamma_file' in self.inputs:
gamma_file = self.inputs.gamma_file
gamma_file_info = (gamma_file.uuid, gamma_file.filename, gamma_file.filename)
calcinfo.local_copy_list.append(gamma_file_info)
# Check if the parent folder is an XspectraCalculation type, if so we then copy the
# save file to enable calculation restarts and re-plots.
parent_folder = self.inputs.parent_folder
parent_calc = parent_folder.creator
if parent_calc.process_type == 'aiida.calculations:quantumespresso.xspectra':
calcinfo.remote_copy_list.append((
parent_folder.computer.uuid, os.path.join(parent_folder.get_remote_path(),
self._XSPECTRA_SAVE_FILE), '.'
))
return calcinfo