def pybuild_wavefunction(mol, basis=None): if basis is None: basis, ecpbasis = core.BasisSet.build(mol) elif (sys.version_info[0] == 2) and isinstance(basis, (str, unicode)): basis, ecpbasis = core.BasisSet.build(mol, "ORBITAL", basis) elif (sys.version_info[0] > 2) and isinstance(basis, str): basis, ecpbasis = core.BasisSet.build(mol, "ORBITAL", basis) if ecpbasis: wfn = core.Wavefunction(mol, basis, ecpbasis) else: wfn = core.Wavefunction(mol, basis) return wfn
def pybuild_wavefunction(mol, basis=None): if basis is None: basis = core.BasisSet.build(mol) elif isinstance(basis, (str, unicode)): basis = core.BasisSet.build(mol, "ORBITAL", basis) return core.Wavefunction(mol, basis)
def _core_wavefunction_build(mol, basis=None): if basis is None: basis = core.BasisSet.build(mol) elif isinstance(basis, str): basis = core.BasisSet.build(mol, "ORBITAL", basis) wfn = core.Wavefunction(mol, basis) # Set basis for density-fitted calculations to the zero basis... # ...until the user explicitly provides a DF basis. wfn.set_basisset("DF_BASIS_SCF", core.BasisSet.zero_ao_basis_set()) return wfn
def pybuild_wavefunction(mol, basis=None): if basis is None: basis = core.BasisSet.build(mol) elif (sys.version_info[0] == 2) and isinstance(basis, (str, unicode)): basis = core.BasisSet.build(mol, "ORBITAL", basis) elif (sys.version_info[0] > 2) and isinstance(basis, str): basis = core.BasisSet.build(mol, "ORBITAL", basis) wfn = core.Wavefunction(mol, basis) # Set basis for density-fitted calculations to the zero basis... # ...until the user explicitly provides a DF basis. wfn.set_basisset("DF_BASIS_SCF", core.BasisSet.zero_ao_basis_set()) return wfn
def _core_wavefunction_from_file( wfn_data: Union[str, Dict, Path]) -> core.Wavefunction: r"""Build Wavefunction from data. Parameters ---------- wfn_data If a dict, use data directly. Otherwise, path-like passed to :py:func:`numpy.load` to read from disk. Returns ------- Wavefunction A deserialized Wavefunction object """ # load the wavefunction from file if isinstance(wfn_data, dict): pass elif isinstance(wfn_data, str): if not wfn_data.endswith(".npy"): wfn_data = wfn_data + ".npy" wfn_data = np.load(wfn_data, allow_pickle=True).item() else: # Could be path-like or file-like, let `np.load` handle it wfn_data = np.load(wfn_data, allow_pickle=True).item() # variable type specific dictionaries to be passed into C++ constructor wfn_matrix = wfn_data['matrix'] wfn_vector = wfn_data['vector'] wfn_dimension = wfn_data['dimension'] wfn_int = wfn_data['int'] wfn_string = wfn_data['string'] wfn_boolean = wfn_data['boolean'] wfn_float = wfn_data['float'] wfn_floatvar = wfn_data['floatvar'] wfn_matrixarr = wfn_data['matrixarr'] # reconstruct molecule from dictionary representation wfn_molecule = wfn_data['molecule'] molecule = core.Molecule.from_dict(wfn_molecule) # get basis set name and spherical harmonics boolean basis_name = wfn_string['basisname'] if ".gbs" in basis_name: basis_name = basis_name.split('/')[-1].replace('.gbs', '') basis_puream = wfn_boolean['basispuream'] basisset = core.BasisSet.build(molecule, 'ORBITAL', basis_name, puream=basis_puream) # change some variables to psi4 specific data types (Matrix, Vector, Dimension) for label in wfn_matrix: array = wfn_matrix[label] wfn_matrix[label] = core.Matrix.from_array( array, name=label) if array is not None else None for label in wfn_vector: array = wfn_vector[label] wfn_vector[label] = core.Vector.from_array( array, name=label) if array is not None else None for label in wfn_dimension: tup = wfn_dimension[label] wfn_dimension[label] = core.Dimension.from_list( tup, name=label) if tup is not None else None for label in wfn_matrixarr: array = wfn_matrixarr[label] wfn_matrixarr[label] = core.Matrix.from_array( array, name=label) if array is not None else None # make the wavefunction wfn = core.Wavefunction(molecule, basisset, wfn_matrix, wfn_vector, wfn_dimension, wfn_int, wfn_string, wfn_boolean, wfn_float) # some of the wavefunction's variables can be changed directly for k, v in wfn_floatvar.items(): wfn.set_variable(k, v) for k, v in wfn_matrixarr.items(): wfn.set_variable(k, v) return wfn
def _basis_projection(self, oldcalc, newcalc): # There's a bug in Psi4 upcasting between custom basis sets # https://github.com/psi4/psi4/issues/719, so we do it ourselves. start_time = time.time() assert (oldcalc.B, oldcalc.Z) != (newcalc.B, newcalc.Z) read_filename = self._fmt_mo_fn(oldcalc) old_wfn = core.Wavefunction.from_file(read_filename) Ca_occ = old_wfn.Ca_subset('SO', 'OCC') Cb_occ = old_wfn.Cb_subset('SO', 'OCC') puream = old_wfn.basisset().has_puream() old_molecule = self.molecule(oldcalc) with psiopts('BASIS %s' % self.basis_sets[oldcalc.Z]): old_basis = core.BasisSet.build(old_molecule, "ORBITAL", self.basis_sets[oldcalc.Z], puream=puream) if isinstance(old_basis, tuple) and len(old_basis) == 2: # newer versions of psi return a second ECP basis old_basis = old_basis[0] new_molecule = self.molecule(newcalc) with psiopts('BASIS %s' % self.basis_sets[newcalc.Z]): new_basis = core.BasisSet.build(new_molecule, 'ORBITAL', self.basis_sets[newcalc.Z], puream=puream) if isinstance(new_basis, tuple) and len(new_basis) == 2: # newer versions of psi return a second ECP basis base_wfn = core.Wavefunction(new_molecule, *new_basis) new_basis = new_basis[0] else: base_wfn = core.Wavefunction(new_molecule, new_basis) nso = new_basis.nbf() nalphapi = old_wfn.nalphapi() nbetapi = old_wfn.nbetapi() na = nalphapi.to_tuple()[0] nb = nbetapi.to_tuple()[0] pCa_occ = base_wfn.basis_projection(Ca_occ, nalphapi, old_basis, new_basis) pCb_occ = base_wfn.basis_projection(Cb_occ, nbetapi, old_basis, new_basis) pCa = np.zeros((nso, nso)) pCb = np.zeros((nso, nso)) pCa[:, :na] = pCa_occ.np[:, :] pCb[:, :nb] = pCb_occ.np[:, :] new_wfn = old_wfn.to_file() new_wfn['matrix']['Ca'] = pCa new_wfn['matrix']['Cb'] = pCb new_wfn['dimension']['nsopi'] = (nso, ) new_wfn['dimension']['nmopi'] = (nso, ) new_wfn['int']['nso'] = nso new_wfn['int']['nmo'] = nso new_wfn['molecule'] = new_molecule.to_dict() new_wfn['string']['basisname'] = new_basis.name() core.print_out( '\n Computing basis set projection from {calc1} to {calc2} (elapsed={time:.2f})\n' .format( calc1=self._display_name(oldcalc).lower(), calc2=self._display_name(newcalc).lower(), time=time.time() - start_time, )) return core.Wavefunction.from_file(new_wfn)
def run_cfour(name, **kwargs): """Function that prepares environment and input files for a calculation calling Stanton and Gauss's CFOUR code. Also processes results back into Psi4 format. This function is not called directly but is instead called by :py:func:`~psi4.driver.energy` or :py:func:`~psi4.driver.optimize` when a Cfour method is requested (through *name* argument). In order to function correctly, the Cfour executable ``xcfour`` must be present in :envvar:`PATH` or :envvar:`PSIPATH`. .. hlist:: :columns: 1 * Many :ref:`PSI Variables <apdx:cfour_psivar>` extracted from the Cfour output * Python dictionary of associated file constants accessible as ``P4C4_INFO['zmat']``, ``P4C4_INFO['output']``, ``P4C4_INFO['grd']``, *etc.* :type name: str :param name: ``'c4-scf'`` || ``'c4-ccsd(t)'`` || ``'cfour'`` || etc. First argument, usually unlabeled. Indicates the computational method to be applied to the system. :type keep: :ref:`boolean <op_py_boolean>` :param keep: ``'on'`` || |dl| ``'off'`` |dr| Indicates whether to delete the Cfour scratch directory upon completion of the Cfour job. :type path: str :param path: Indicates path to Cfour scratch directory (with respect to Psi4 scratch directory). Otherwise, the default is a subdirectory within the Psi4 scratch directory. If specified, GENBAS and/or ZMAT within will be used. :type genbas: str :param genbas: Indicates that contents should be used for GENBAS file. GENBAS is a complicated topic. It is quite unnecessary if the molecule is from a molecule {...} block and basis is set through |Psifours| BASIS keyword. In that case, a GENBAS is written from LibMints and all is well. Otherwise, a GENBAS is looked for in the usual places: PSIPATH, PATH, PSIDATADIR/basis. If path kwarg is specified, also looks there preferentially for a GENBAS. Can also specify GENBAS within an input file through a string and setting the genbas kwarg. Note that due to the input parser's aggression, blank lines need to be replaced by the text blankline. """ lowername = name.lower() internal_p4c4_info = {} return_wfn = kwargs.pop('return_wfn', False) # Make sure the molecule the user provided is the active one molecule = kwargs.pop('molecule', core.get_active_molecule()) molecule.update_geometry() optstash = p4util.OptionsState(['CFOUR', 'TRANSLATE_PSI4']) # Determine calling function and hence dertype calledby = inspect.stack()[1][3] dertype = ['energy', 'gradient', 'hessian'].index(calledby) #print('I am %s called by %s called by %s.\n' % # (inspect.stack()[0][3], inspect.stack()[1][3], inspect.stack()[2][3])) # Save submission directory current_directory = os.getcwd() # Move into job scratch directory psioh = core.IOManager.shared_object() psio = core.IO.shared_object() os.chdir(psioh.get_default_path()) # Construct and move into cfour subdirectory of job scratch directory cfour_tmpdir = kwargs['path'] if 'path' in kwargs else \ 'psi.' + str(os.getpid()) + '.' + psio.get_default_namespace() + \ '.cfour.' + str(uuid.uuid4())[:8] if not os.path.exists(cfour_tmpdir): os.mkdir(cfour_tmpdir) os.chdir(cfour_tmpdir) # Find environment by merging PSIPATH and PATH environment variables lenv = { 'PATH': ':'.join([ os.path.abspath(x) for x in os.environ.get('PSIPATH', '').split(':') if x != '' ]) + ':' + os.environ.get('PATH') + ':' + core.get_datadir() + '/basis', 'GENBAS_PATH': core.get_datadir() + '/basis', 'CFOUR_NUM_CORES': os.environ.get('CFOUR_NUM_CORES'), 'MKL_NUM_THREADS': os.environ.get('MKL_NUM_THREADS'), 'OMP_NUM_THREADS': os.environ.get('OMP_NUM_THREADS'), 'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH') } if 'path' in kwargs: lenv['PATH'] = kwargs['path'] + ':' + lenv['PATH'] # Filter out None values as subprocess will fault on them lenv = {k: v for k, v in lenv.items() if v is not None} # Load the GENBAS file genbas_path = qcdb.search_file('GENBAS', lenv['GENBAS_PATH']) if genbas_path: try: shutil.copy2(genbas_path, psioh.get_default_path() + cfour_tmpdir) except shutil.Error: # should only fail if src and dest equivalent pass core.print_out("\n GENBAS loaded from %s\n" % (genbas_path)) core.print_out(" CFOUR to be run from %s\n" % (psioh.get_default_path() + cfour_tmpdir)) else: message = """ GENBAS file for CFOUR interface not found. Either: [1] Supply a GENBAS by placing it in PATH or PSIPATH [1a] Use cfour {} block with molecule and basis directives. [1b] Use molecule {} block and CFOUR_BASIS keyword. [2] Allow Psi4's internal basis sets to convert to GENBAS [2a] Use molecule {} block and BASIS keyword. """ core.print_out(message) core.print_out(' Search path that was tried:\n') core.print_out(lenv['PATH'].replace(':', ', ')) # Generate the ZMAT input file in scratch if 'path' in kwargs and os.path.isfile('ZMAT'): core.print_out(" ZMAT loaded from %s\n" % (psioh.get_default_path() + kwargs['path'] + '/ZMAT')) else: with open('ZMAT', 'w') as cfour_infile: cfour_infile.write(write_zmat(lowername, dertype, molecule)) internal_p4c4_info['zmat'] = open('ZMAT', 'r').read() #core.print_out('\n====== Begin ZMAT input for CFOUR ======\n') #core.print_out(open('ZMAT', 'r').read()) #core.print_out('======= End ZMAT input for CFOUR =======\n\n') #print('\n====== Begin ZMAT input for CFOUR ======') #print(open('ZMAT', 'r').read()) #print('======= End ZMAT input for CFOUR =======\n') if 'genbas' in kwargs: with open('GENBAS', 'w') as cfour_basfile: cfour_basfile.write(kwargs['genbas'].replace( '\nblankline\n', '\n\n')) core.print_out(' GENBAS loaded from kwargs string\n') # Close psi4 output file and reopen with filehandle print('output in', current_directory + '/' + core.outfile_name()) pathfill = '' if os.path.isabs( core.outfile_name()) else current_directory + os.path.sep # Handle threading # OMP_NUM_THREADS from env is in lenv from above # threads from psi4 -n (core.get_num_threads()) is ignored # CFOUR_OMP_NUM_THREADS psi4 option takes precedence, handled below if core.has_option_changed('CFOUR', 'CFOUR_OMP_NUM_THREADS'): lenv['OMP_NUM_THREADS'] = str( core.get_option('CFOUR', 'CFOUR_OMP_NUM_THREADS')) #print("""\n\n<<<<< RUNNING CFOUR ... >>>>>\n\n""") # Call executable xcfour, directing cfour output to the psi4 output file cfour_executable = kwargs['c4exec'] if 'c4exec' in kwargs else 'xcfour' try: retcode = subprocess.Popen([cfour_executable], bufsize=0, stdout=subprocess.PIPE, env=lenv) except OSError as e: sys.stderr.write( 'Program %s not found in path or execution failed: %s\n' % (cfour_executable, e.strerror)) message = ('Program %s not found in path or execution failed: %s\n' % (cfour_executable, e.strerror)) raise ValidationError(message) c4out = '' while True: data = retcode.stdout.readline() data = data.decode('utf-8') if not data: break core.print_out(data) c4out += data internal_p4c4_info['output'] = c4out c4files = {} core.print_out('\n') for item in ['GRD', 'FCMFINAL', 'DIPOL']: try: with open(psioh.get_default_path() + cfour_tmpdir + '/' + item, 'r') as handle: c4files[item] = handle.read() core.print_out(' CFOUR scratch file %s has been read\n' % (item)) core.print_out('%s\n' % c4files[item]) internal_p4c4_info[item.lower()] = c4files[item] except IOError: pass core.print_out('\n') if molecule.name() == 'blank_molecule_psi4_yo': qcdbmolecule = None else: molecule.update_geometry() qcdbmolecule = qcdb.Molecule( molecule.create_psi4_string_from_molecule()) qcdbmolecule.update_geometry() # c4mol, if it exists, is dinky, just a clue to geometry of cfour results psivar, c4grad, c4mol = qcdb.cfour.harvest(qcdbmolecule, c4out, **c4files) # Absorb results into psi4 data structures for key in psivar.keys(): core.set_variable(key.upper(), float(psivar[key])) if qcdbmolecule is None and c4mol is not None: molrec = qcel.molparse.from_string( c4mol.create_psi4_string_from_molecule(), enable_qm=True, missing_enabled_return_qm='minimal', enable_efp=False, missing_enabled_return_efp='none', ) molecule = core.Molecule.from_dict(molrec['qm']) molecule.set_name('blank_molecule_psi4_yo') core.set_active_molecule(molecule) molecule.update_geometry() # This case arises when no Molecule going into calc (cfour {} block) but want # to know the orientation at which grad, properties, etc. are returned (c4mol). # c4mol is dinky, w/o chg, mult, dummies and retains name # blank_molecule_psi4_yo so as to not interfere with future cfour {} blocks if c4grad is not None: mat = core.Matrix.from_list(c4grad) core.set_gradient(mat) #print ' <<< [3] C4-GRD-GRAD >>>' #mat.print() # exit(1) # # Things needed core.so module to do # collect c4out string # read GRD # read FCMFINAL # see if theres an active molecule # # Things delegatable to qcdb # parsing c4out # reading GRD and FCMFINAL strings # reconciling p4 and c4 molecules (orient) # reconciling c4out and GRD and FCMFINAL results # transforming frame of results back to p4 # # Things run_cfour needs to have back # psivar # qcdb.Molecule of c4? # coordinates? # gradient in p4 frame # # Process the cfour output # psivar, c4coord, c4grad = qcdb.cfour.cfour_harvest(c4out) # for key in psivar.keys(): # core.set_variable(key.upper(), float(psivar[key])) # # # Awful Hack - Go Away TODO # if c4grad: # molecule = core.get_active_molecule() # molecule.update_geometry() # # if molecule.name() == 'blank_molecule_psi4_yo': # p4grad = c4grad # p4coord = c4coord # else: # qcdbmolecule = qcdb.Molecule(molecule.create_psi4_string_from_molecule()) # #p4grad = qcdbmolecule.deorient_array_from_cfour(c4coord, c4grad) # #p4coord = qcdbmolecule.deorient_array_from_cfour(c4coord, c4coord) # # with open(psioh.get_default_path() + cfour_tmpdir + '/GRD', 'r') as cfour_grdfile: # c4outgrd = cfour_grdfile.read() # print('GRD\n',c4outgrd) # c4coordGRD, c4gradGRD = qcdb.cfour.cfour_harvest_files(qcdbmolecule, grd=c4outgrd) # # p4mat = core.Matrix.from_list(p4grad) # core.set_gradient(p4mat) # print(' <<< P4 PSIVAR >>>') # for item in psivar: # print(' %30s %16.8f' % (item, psivar[item])) #print(' <<< P4 COORD >>>') #for item in p4coord: # print(' %16.8f %16.8f %16.8f' % (item[0], item[1], item[2])) # print(' <<< P4 GRAD >>>') # for item in c4grad: # print(' %16.8f %16.8f %16.8f' % (item[0], item[1], item[2])) # Clean up cfour scratch directory unless user instructs otherwise keep = yes.match(str(kwargs['keep'])) if 'keep' in kwargs else False os.chdir('..') try: if keep or ('path' in kwargs): core.print_out('\n CFOUR scratch files have been kept in %s\n' % (psioh.get_default_path() + cfour_tmpdir)) else: shutil.rmtree(cfour_tmpdir) except OSError as e: print('Unable to remove CFOUR temporary directory %s' % e, file=sys.stderr) exit(1) # Return to submission directory and reopen output file os.chdir(current_directory) core.print_out('\n') p4util.banner(' Cfour %s %s Results ' % (name.lower(), calledby.capitalize())) core.print_variables() if c4grad is not None: core.get_gradient().print_out() core.print_out('\n') p4util.banner(' Cfour %s %s Results ' % (name.lower(), calledby.capitalize())) core.print_variables() if c4grad is not None: core.get_gradient().print_out() # Quit if Cfour threw error if 'CFOUR ERROR CODE' in core.variables(): raise ValidationError("""Cfour exited abnormally.""") P4C4_INFO.clear() P4C4_INFO.update(internal_p4c4_info) optstash.restore() # new skeleton wavefunction w/mol, highest-SCF basis (just to choose one), & not energy # Feb 2017 hack. Could get proper basis in skel wfn even if not through p4 basis kw if core.get_global_option('BASIS') in ["", "(AUTO)"]: gobas = "sto-3g" else: gobas = core.get_global_option('BASIS') basis = core.BasisSet.build(molecule, "ORBITAL", gobas) if basis.has_ECP(): raise ValidationError("""ECPs not hooked up for Cfour""") wfn = core.Wavefunction(molecule, basis) for k, v in psivar.items(): wfn.set_variable(k.upper(), float(v)) optstash.restore() if dertype == 0: finalquantity = psivar['CURRENT ENERGY'] elif dertype == 1: finalquantity = core.get_gradient() wfn.set_gradient(finalquantity) if finalquantity.rows(0) < 20: core.print_out('CURRENT GRADIENT') finalquantity.print_out() elif dertype == 2: pass #finalquantity = finalhessian #wfn.set_hessian(finalquantity) #if finalquantity.rows(0) < 20: # core.print_out('CURRENT HESSIAN') # finalquantity.print_out() return wfn
def _core_wavefunction_from_file(wfn_data): # load the wavefunction from file if isinstance(wfn_data, str): wfn_data = np.load(wfn_data + '.npy').item() # otherwise a dictionary was passed in else: pass # variable type specific dictionaries to be passed into C++ constructor wfn_matrix = wfn_data['matrix'] wfn_vector = wfn_data['vector'] wfn_dimension = wfn_data['dimension'] wfn_int = wfn_data['int'] wfn_string = wfn_data['string'] wfn_boolean = wfn_data['boolean'] wfn_float = wfn_data['float'] wfn_floatvar = wfn_data['floatvar'] wfn_matrixarr = wfn_data['matrixarr'] # reconstruct molecule from dictionary representation wfn_molecule = wfn_data['molecule'] molecule = core.Molecule.from_dict(wfn_molecule) # get basis set name and spherical harmonics boolean basis_name = wfn_string['basisname'] if ".gbs" in basis_name: basis_name = basis_name.split('/')[-1].replace('.gbs', '') basis_puream = wfn_boolean['basispuream'] basisset = core.BasisSet.build(molecule, 'ORBITAL', basis_name, puream=basis_puream) # change some variables to psi4 specific data types (Matrix, Vector, Dimension) for label in wfn_matrix: array = wfn_matrix[label] wfn_matrix[label] = core.Matrix.from_array( array, name=label) if array is not None else None for label in wfn_vector: array = wfn_vector[label] wfn_vector[label] = core.Vector.from_array( array, name=label) if array else None for label in wfn_dimension: tup = wfn_dimension[label] wfn_dimension[label] = core.Dimension.from_list( tup, name=label) if tup else None for label in wfn_matrixarr: array = wfn_dimension[label] wfn_dimension[label] = core.Matrix.from_array( array, name=label) if array else None # make the wavefunction wfn = core.Wavefunction(molecule, basisset, wfn_matrix, wfn_vector, wfn_dimension, wfn_int, wfn_string, wfn_boolean, wfn_float) # some of the wavefunction's variables can be changed directly for k, v in wfn_floatvar.items(): wfn.set_variable(k, v) for k, v in wfn_matrixarr.items(): wfn.set_variable(k, v) return wfn
def _basis_projection(self, oldcalc, newcalc): # There's a bug in Psi4 upcasting between custom basis sets # https://github.com/psi4/psi4/issues/719, so we do it ourselves. start_time = time.time() assert (oldcalc.B, oldcalc.Z) != (newcalc.B, newcalc.Z) read_filename = self._fmt_mo_fn(oldcalc) data = np.load(read_filename) Ca_occ = core.Matrix.np_read(data, "Ca_occ") Cb_occ = core.Matrix.np_read(data, "Cb_occ") puream = int(data["BasisSet PUREAM"]) old_molecule = self.molecule(oldcalc) with psiopts('BASIS %s' % self.basis_sets[oldcalc.Z]): old_basis = core.BasisSet.build(old_molecule, "ORBITAL", self.basis_sets[oldcalc.Z], puream=puream) if isinstance(old_basis, tuple) and len(old_basis) == 2: # newer versions of psi return a second ECP basis old_basis = old_basis[0] new_molecule = self.molecule(newcalc) with psiopts('BASIS %s' % self.basis_sets[newcalc.Z]): new_basis = core.BasisSet.build(new_molecule, 'ORBITAL', self.basis_sets[newcalc.Z], puream=puream) if isinstance(new_basis, tuple) and len(new_basis) == 2: # newer versions of psi return a second ECP basis base_wfn = core.Wavefunction(new_molecule, *new_basis) new_basis = new_basis[0] else: base_wfn = core.Wavefunction(new_molecule, new_basis) nalphapi = core.Dimension.from_list(data["nalphapi"]) nbetapi = core.Dimension.from_list(data["nbetapi"]) pCa = base_wfn.basis_projection(Ca_occ, nalphapi, old_basis, new_basis) pCb = base_wfn.basis_projection(Cb_occ, nbetapi, old_basis, new_basis) new_data = {} new_data.update(pCa.np_write(None, prefix="Ca_occ")) new_data.update(pCb.np_write(None, prefix="Cb_occ")) new_data["reference"] = core.get_option('SCF', 'REFERENCE') new_data["symmetry"] = new_molecule.schoenflies_symbol() new_data["BasisSet"] = new_basis.name() new_data["BasisSet PUREAM"] = puream core.print_out( '\n Computing basis set projection from {calc1} to {calc2} (elapsed={time:.2f})\n' .format( calc1=self._display_name(oldcalc).lower(), calc2=self._display_name(newcalc).lower(), time=time.time() - start_time, )) # Workaround for https://github.com/psi4/psi4/pull/750 for key, value in new_data.items(): if isinstance(value, np.ndarray) and value.flags['OWNDATA'] == False: new_data[key] = np.copy(value) return new_data