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)
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)
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))