def parse(self, **kwargs):
        """Parse the retrieved files of a completed `Pw2wannierCalculation` into output nodes.

        Two nodes that are expected are the default 'retrieved' `FolderData` node which will store the retrieved files
        permanently in the repository.
        """
        try:
            out_folder = self.retrieved
        except NotExistent:
            return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)

        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:
                out_file = fil.read()
        except OSError:
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

        parsed_data, logs = parse_output_base(out_file, codename='PW2WANNIER')
        self.emit_logs(logs)

        self.out('output_parameters', Dict(dict=parsed_data))

        if 'ERROR_OUTPUT_STDOUT_INCOMPLETE' in logs.error:
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE)
        elif logs.error:
            return self.exit(self.exit_codes.ERROR_GENERIC_QE_ERROR)
Example #2
0
    def parse(self, **kwargs):
        """Parses the datafolder, stores results.

        Retrieves projwfc output, and some basic information from the out_file, such as warnings and wall_time
        """
        # Check that the retrieved folder is there
        try:
            out_folder = self.retrieved
        except NotExistent:
            return self.exit(self.exit_codes.ERROR_NO_RETRIEVED_FOLDER)

        # 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:
                out_file = fil.readlines()
        except OSError:
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

        job_done = False
        for i in range(len(out_file)):
            line = out_file[-i]
            if 'JOB DONE' in line:
                job_done = True
                break
        if not job_done:
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE)

        # Parse basic info and warnings, and output them as output_parmeters
        parsed_data, logs = parse_output_base(out_file, 'PROJWFC')
        self.emit_logs(logs)
        self.out('output_parameters', Dict(dict=parsed_data))

        # check and read pdos_tot file
        out_filenames = out_folder.list_object_names()
        try:
            pdostot_filename = fnmatch.filter(out_filenames, '*pdos_tot*')[0]
            with out_folder.open(pdostot_filename, 'r') as pdostot_file:
                # Columns: Energy(eV), Ldos, Pdos
                pdostot_array = np.atleast_2d(np.genfromtxt(pdostot_file))
                energy = pdostot_array[:, 0]
                dos = pdostot_array[:, 1]
        except (OSError, KeyError):
            return self.exit(self.exit_codes.ERROR_READING_PDOSTOT_FILE)

        # check and read all of the individual pdos_atm files
        pdos_atm_filenames = fnmatch.filter(out_filenames, '*pdos_atm*')
        pdos_atm_array_dict = {}
        for name in pdos_atm_filenames:
            with out_folder.open(name, 'r') as pdosatm_file:
                pdos_atm_array_dict[name] = np.atleast_2d(
                    np.genfromtxt(pdosatm_file))

        # finding the bands and projections
        # we create a dictionary the progressively accumulates more info
        out_info_dict = {}
        out_info_dict['out_file'] = out_file
        out_info_dict['energy'] = energy
        out_info_dict['pdos_atm_array_dict'] = pdos_atm_array_dict
        try:
            new_nodes_list = self._parse_bands_and_projections(out_info_dict)
        except QEOutputParsingError as err:
            self.logger.error(
                'Error parsing bands and projections: {}'.format(err))
            return self.exit(self.exit_codes.ERROR_PARSING_PROJECTIONS)
        for linkname, node in new_nodes_list:
            self.out(linkname, node)

        Dos_out = XyData()
        Dos_out.set_x(energy, 'Energy', 'eV')
        Dos_out.set_y(dos, 'Dos', 'states/eV')
        self.out('Dos', Dos_out)
Example #3
0
    def parse(self, **kwargs):
        """Parses the datafolder, stores results.

        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)

        # 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:
                out_file = fil.readlines()
        except OSError:
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)

        job_done = False
        for i in range(len(out_file)):
            line = out_file[-i]
            if 'JOB DONE' in line:
                job_done = True
                break
        if not job_done:
            return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE)

        # 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:
                dos_file = fil.readlines()
        except OSError:
            return self.exit(self.exit_codes.ERROR_READING_DOS_FILE)

        # end of initial checks

        array_names = [[], []]
        array_units = [[], []]
        array_names[0] = ['dos_energy', 'dos',
                          'integrated_dos']  # When spin is not displayed
        array_names[1] = [
            'dos_energy', 'dos_spin_up', 'dos_spin_down', 'integrated_dos'
        ]  # When spin is displayed
        array_units[0] = ['eV', 'states/eV',
                          'states']  # When spin is not displayed
        array_units[1] = ['eV', 'states/eV', 'states/eV',
                          'states']  # When spin is displayed

        # grabs parsed data from aiida.dos
        # TODO: should I catch any QEOutputParsingError from parse_raw_dos,
        #       log an error and return an exit code?
        array_data, spin = parse_raw_dos(dos_file, array_names, array_units)

        energy_units = 'eV'
        dos_units = 'states/eV'
        int_dos_units = 'states'
        xy_data = XyData()
        xy_data.set_x(array_data['dos_energy'], 'dos_energy', energy_units)
        y_arrays = []
        y_names = []
        y_units = []
        y_arrays += [array_data['integrated_dos']]
        y_names += ['integrated_dos']
        y_units += ['states']
        if spin:
            y_arrays += [array_data['dos_spin_up']]
            y_arrays += [array_data['dos_spin_down']]
            y_names += ['dos_spin_up']
            y_names += ['dos_spin_down']
            y_units += ['states/eV'] * 2
        else:
            y_arrays += [array_data['dos']]
            y_names += ['dos']
            y_units += ['states/eV']
        xy_data.set_y(y_arrays, y_names, y_units)

        parsed_data, logs = parse_output_base(out_file, 'DOS')
        self.emit_logs(logs)

        self.out('output_dos', xy_data)
        self.out('output_parameters', Dict(dict=parsed_data))