def get_output_from_qchem(input_qchem, processors=1, use_mpi=False, scratch=None, read_fchk=False, parser=None, parser_parameters=None, force_recalculation=False, fchk_only=False, store_full_output=False, remove_scratch=True, remote=None, strict_policy=False): """ Runs qchem and returns the output in the following format: 1) If read_fchk is requested: [output, parsed_fchk] 2) If read_fchk is not requested: [output] Note: if parser is set then output contains a dictionary with the parsed info else output contains the q-chem output in plain text read_fchk: contains a dictionary with the parsed info inside fchk file. :param input_qchem: QcInput object containing the Q-Chem input :param processors: number of threads/processors to use in the calculation :param use_mpi: If False use OpenMP (threads) else use MPI (processors) :param scratch: Full Q-Chem scratch directory path. If None read from $QCSCRATCH :param read_fchk: if True, generate and parse the FCHK file containing the electronic structure :param parser: function to use to parse the Q-Chem output :param parser_parameters: additional parameters that parser function may have :param force_recalculation: Force to recalculate even identical calculation has already performed :param fchk_only: If true, returns only the electronic structure data parsed from FCHK file :param remote: dictionary containing the data for remote calculation (beta) :return: output [, fchk_dict] """ from pyqchem.parsers.parser_fchk import parser_fchk # check gui > 2 if read_fchk if read_fchk: if input_qchem.gui is None or input_qchem.gui < 1: input_qchem.gui = 2 if scratch is None: scratch = os.getenv('QCSCRATCH') work_dir = '{}/qchem{}/'.format(scratch, os.getpid()) try: os.mkdir(work_dir) except OSError: pass # handle custom guess if input_qchem.mo_coefficients is not None: input_qchem.store_mo_file(work_dir) # set scf energy if skip_scfman (to not break) # TODO: now SCF energy is set to zero. This works for very little features. if input_qchem._skip_scfman: input_qchem.store_energy_file(work_dir) # check if hessian if input_qchem.hessian is not None: ndim = len(input_qchem.hessian) hessian_triu = np.array(input_qchem.hessian) with open(work_dir + '132.0', 'w') as f: hessian_triu.tofile(f, sep='') input_txt = input_qchem.get_txt() # check if parameters is None if parser_parameters is None: parser_parameters = {} # check if full output is stored # print('input:', input_qchem) output, err = calculation_data[(hash(input_qchem), 'fullout')] if ( hash(input_qchem), 'fullout') in calculation_data else [None, None] # output, err = retrieve_calculation_data(input_qchem, 'fullout') if retrieve_calculation_data(input_qchem, 'fullout') is not None else [None, None] if not force_recalculation and not store_full_output: data_fchk = retrieve_calculation_data(input_qchem, 'fchk') if parser is not None: data = retrieve_calculation_data(hash(input_qchem), parser.__name__) if data is not None: if read_fchk is False: return data elif data_fchk is not None: return data, data_fchk else: force_recalculation = True else: if fchk_only and data_fchk is not None: return None, data_fchk fchk_filename = 'qchem_temp_{}.fchk'.format(os.getpid()) temp_filename = 'qchem_temp_{}.inp'.format(os.getpid()) qchem_input_file = open(os.path.join(work_dir, temp_filename), mode='w') qchem_input_file.write(input_txt) qchem_input_file.close() # Q-Chem calculation if output is None or force_recalculation is True: if remote is None: output, err = local_run(temp_filename, work_dir, fchk_filename, use_mpi=use_mpi, processors=processors) else: output, err = remote_run(temp_filename, work_dir, fchk_filename, remote, use_mpi=use_mpi, processors=processors) if not finish_ok(output): raise OutputError(output, err) if store_full_output: store_calculation_data(input_qchem, 'fullout', [output, err]) if parser is not None: try: output = parser(output, **parser_parameters) # minimum functionality for error capture except: raise ParserError(parser.__name__, 'Undefined error') store_calculation_data(input_qchem, parser.__name__, output) if read_fchk: data_fchk = retrieve_calculation_data(input_qchem, 'fchk') if data_fchk is not None and not force_recalculation: return output, data_fchk if not os.path.isfile(os.path.join(work_dir, fchk_filename)): warnings.warn( 'fchk not found! Make sure the input generates it (gui 2)') return output, [] with open(os.path.join(work_dir, fchk_filename)) as f: fchk_txt = f.read() os.remove(os.path.join(work_dir, fchk_filename)) data_fchk = parser_fchk(fchk_txt) store_calculation_data(input_qchem, 'fchk', data_fchk) return output, data_fchk if remove_scratch: shutil.rmtree(work_dir) return output
:return: """ # Get xyz file format from Molecule or Geometry (or list) if not isinstance(structures, list): structures = [structures] txt = '' for structure in structures: txt += '{}\n'.format(structure.get_number_of_atoms()) txt += '{}\n'.format( structure.name if structure.name is not None else '') for idp, position in enumerate(structure.get_coordinates()): txt += '{:2} {:11.6f} {:11.6f} {:11.6f}\n'.format( structure.get_symbols()[idp], position[0], position[1], position[2]) with open(filename, 'w') as f: f.write(txt) if __name__ == '__main__': from pyqchem.parsers.parser_fchk import parser_fchk txt_fchk = open('qchem_temp_32947.fchk', 'r').read() parsed_data = parser_fchk(txt_fchk) txt_fchk_new = build_fchk(parsed_data) with open('test.fchk', 'w') as f: f.write(txt_fchk_new) #structure, basis, alpha_coeff, beta_coeff = get_data_from_file_fchk('qchem_temp_32947.fchk') #print(basis)
def get_output_from_qchem(input_qchem, processors=1, use_mpi=False, scratch=None, read_fchk=False, parser=None, parser_parameters=None, force_recalculation=False, fchk_only=False, store_full_output=False, delete_scratch=True, remote=None): """ Runs qchem and returns the output in the following format: 1) If read_fchk is requested: [output, parsed_fchk] 2) If read_fchk is not requested: [output] Note: if parser is set then output contains a dictionary with the parsed info else output contains the q-chem output in plain text read_fchk: contains a dictionary with the parsed info inside fchk file. :param input_qchem: QcInput object containing the Q-Chem input :param processors: number of threads/processors to use in the calculation :param use_mpi: If False use OpenMP (threads) else use MPI (processors) :param scratch: Full Q-Chem scratch directory path. If None read from $QCSCRATCH :param read_fchk: if True, returns the parsed FCHK file containing the electronic structure :param parser: function to use to parse the Q-Chem output :param parser_parameters: additional parameters that parser function may have :param force_recalculation: Force to recalculate even identical calculation has already performed :param fchk_only: If true, returns only the electronic structure data parsed from FCHK file :param remote: dictionary containing the data for remote calculation (beta) :param store_full_output: store full output in plain text in pkl file :param delete_scratch: delete all scratch files when calculation is finished :return: output [, fchk_dict] """ from pyqchem.parsers.parser_fchk import parser_fchk cache = CacheSystem() # Always generate fchk if input_qchem.gui is None or input_qchem.gui < 1: input_qchem.gui = 2 if scratch is None: scratch = os.getenv('QCSCRATCH') if scratch is None: warnings.warn('QCSCRATCH environment variable not defined, using workdir') scratch = '.' work_dir = '{}/pyqchem_{}/'.format(scratch, os.getpid()) try: os.mkdir(work_dir) except OSError: pass # check if parameters is None if parser_parameters is None: parser_parameters = {} # check if full output is stored output = cache.retrieve_calculation_data(input_qchem, 'fullout') #output, err = cache.calculation_data[(hash(input_qchem), 'fullout')] if (hash(input_qchem), 'fullout') in cache.calculation_data else [None, None] data_fchk = cache.retrieve_calculation_data(input_qchem, 'fchk') # check if repeated calculation if not force_recalculation and not store_full_output: # store_full_output always force re-parsing if parser is not None: parsed_data = cache.retrieve_calculation_data(hash(input_qchem), parser.__name__) if parsed_data is not None: if read_fchk: return parsed_data, data_fchk else: return parsed_data else: if fchk_only and data_fchk is not None: return output, data_fchk fchk_filename = 'qchem_temp_{}.fchk'.format(os.getpid()) temp_filename = 'qchem_temp_{}.inp'.format(os.getpid()) # generate the input in TXT form input_txt = input_qchem.get_txt() qchem_input_file = open(os.path.join(work_dir, temp_filename), mode='w') qchem_input_file.write(input_txt) qchem_input_file.close() # generate extra files in calculation directory generate_additional_files(input_qchem, work_dir) # Q-Chem calculation if output is None or force_recalculation is True: if remote is None: output, err = local_run(temp_filename, work_dir, fchk_filename, use_mpi=use_mpi, processors=processors) else: output, err = remote_run(temp_filename, work_dir, fchk_filename, remote, use_mpi=use_mpi, processors=processors) if not finish_ok(output): raise OutputError(output, err) # parse fchk file & and additional scratch dir files if not os.path.isfile(os.path.join(work_dir, fchk_filename)): warnings.warn('fchk not found! something may be wrong in calculation') else: with open(os.path.join(work_dir, fchk_filename)) as f: fchk_txt = f.read() data_fchk = parser_fchk(fchk_txt) data_fchk.update(retrieve_additional_files(input_qchem, data_fchk, work_dir)) cache.store_calculation_data(input_qchem, 'fchk', data_fchk) if store_full_output: cache.store_calculation_data(input_qchem, 'fullout', output) if parser is not None: # Check parser compatibility version = get_version_output(output) compatibility_list = get_compatibility_list_from_parser(parser) if compatibility_list is not None: if version not in compatibility_list: warnings.warn('Parser "{}" may not be compatible with Q-Chem {}'.format(parser.__name__, version)) # minimum functionality for parser error capture try: output = parser(output, **parser_parameters) except: raise ParserError(parser.__name__, 'Undefined error') cache.store_calculation_data(input_qchem, parser.__name__, output) if delete_scratch: shutil.rmtree(work_dir) if read_fchk: return output, data_fchk else: return output