示例#1
0
文件: cube.py 项目: andersx/qctoolkit
 def __pow__(self, other):
     if isinstance(other, CUBE):
         ut.exit("power operation is not allowed between CUBE objects")
     else:
         _out = copy.deepcopy(self)
         _out.data = _out.data**other
         return _out
示例#2
0
文件: cube.py 项目: andersx/qctoolkit
 def asGaussianTemplate(self, gcube, **kwargs):
     cube_name_list = gcube.name.split('.')
     fchk_name = '.'.join(cube_name_list[:-1]) + '.fchk'
     fchk = os.path.abspath(os.path.join(gcube.path, fchk_name))
     path, _ = os.path.split(fchk)
     if not os.path.exists(fchk):
         ut.exit("gaussian fchk file:%s not found" % fchk)
     cube = 'gcube_tmp_' + str(id(self)) + '.cube'
     cube = os.path.join(path, cube)
     cmd = '%s 1 density=scf %s %s -1' % (qtk.gaussian_cubegen_exe, fchk,
                                          cube)
     run = sp.Popen(cmd, shell=True, stdin=sp.PIPE)
     for i in range(len(self.grid)):
         vec = self.grid[i]
         if i == 0:
             # for formated output
             msg = '-1 %f %f %f\n' % (vec[1], vec[2], vec[3])
         elif i == 1:
             # for Bohr as grid unit
             msg = '%d %f %f %f\n' % (-vec[0], vec[1], vec[2], vec[3])
         else:
             msg = '%d %f %f %f\n' % (vec[0], vec[1], vec[2], vec[3])
         run.stdin.write(msg)
     run.stdin.flush()
     run.communicate()
     run.wait()
     return qtk.CUBE(cube)
示例#3
0
 def asGaussianTemplate(self, gcube, **kwargs):
   cube_name_list = gcube.name.split('.')
   fchk_name = '.'.join(cube_name_list[:-1]) + '.fchk'
   fchk = os.path.abspath(os.path.join(gcube.path, fchk_name))
   path, _ = os.path.split(fchk)
   if not os.path.exists(fchk):
     ut.exit("gaussian fchk file:%s not found" % fchk)
   cube = 'gcube_tmp_' + str(id(self)) + '.cube'
   cube = os.path.join(path, cube)
   cmd = '%s 1 density=scf %s %s -1' % (qtk.gaussian_cubegen_exe, 
                                        fchk, cube)
   run = sp.Popen(cmd, shell=True, stdin=sp.PIPE)
   for i in range(len(self.grid)):
     vec = self.grid[i]
     if i == 0:
       # for formated output
       msg = '-1 %f %f %f\n' % (vec[1], vec[2], vec[3])
     elif i == 1:
       # for Bohr as grid unit
       msg = '%d %f %f %f\n' % (-vec[0], vec[1], vec[2], vec[3])
     else:
       msg = '%d %f %f %f\n' % (vec[0], vec[1], vec[2], vec[3])
     run.stdin.write(msg)
   run.stdin.flush()
   run.communicate()
   run.wait()
   return qtk.CUBE(cube)
示例#4
0
 def __pow__(self, other):
   if isinstance(other, CUBE):
     ut.exit("power operation is not allowed between CUBE objects")
   else:
     _out = copy.deepcopy(self)
     _out.data = _out.data ** other
     return _out
示例#5
0
文件: cube.py 项目: andersx/qctoolkit
 def isCubic(self):
     grid_vector = self.grid[1:, 1:]
     diff = np.linalg.norm(grid_vector, axis=1)\
            - np.sum(grid_vector, axis=1)
     if np.linalg.norm(diff) > 1E-8:
         ut.exit("only orthorhombic grid is supported")
         return False
     else:
         return True
示例#6
0
 def isCubic(self):
   grid_vector = self.grid[1:,1:]
   diff = np.linalg.norm(grid_vector, axis=1)\
          - np.sum(grid_vector, axis=1)
   if np.linalg.norm(diff) > 1E-8:
     ut.exit("only orthorhombic grid is supported")
     return False
   else:
     return True
示例#7
0
 def meshgrid(self):
   if self.isCubic():
     def getList(i):
       lim = self.grid[0, 1] + (self.grid[1, 0] - 1) * self.grid[1, 1]
       return np.linspace(self.grid[0, i], lim, self.grid[i, 0])
     x = getList(1)
     y = getList(2)
     z = getList(3)
     ut.warning("CUBE.meshgrid returns in the unit of Bohr!")
     return np.meshgrid(x,y,z, indexing='ij')
   else:
     ut.exit("meshgrid only works for cubical system")
示例#8
0
文件: cube.py 项目: andersx/qctoolkit
 def __div__(self, other):
     if isinstance(other, CUBE):
         _grid = self.grid[1:] - other.grid[1:]
         if (abs(sum(sum(_grid))) < 10**-7):
             _out = copy.deepcopy(self)
             _out.data = np.divide(self.data, other.data)
             return _out
         else:
             ut.exit("ERROR from qmout.py->CUBE: " +\
                      "grid mesh does not match")
     else:
         _out = copy.deepcopy(self)
         _out.data = _out.data / other
         return _out
示例#9
0
文件: cube.py 项目: andersx/qctoolkit
    def meshgrid(self):
        if self.isCubic():

            def getList(i):
                lim = self.grid[0, 1] + (self.grid[1, 0] - 1) * self.grid[1, 1]
                return np.linspace(self.grid[0, i], lim, self.grid[i, 0])

            x = getList(1)
            y = getList(2)
            z = getList(3)
            ut.warning("CUBE.meshgrid returns in the unit of Bohr!")
            return np.meshgrid(x, y, z, indexing='ij')
        else:
            ut.exit("meshgrid only works for cubical system")
示例#10
0
 def __div__(self, other):
   if isinstance(other, CUBE):
     _grid = self.grid[1:] - other.grid[1:]
     if(abs(sum(sum(_grid))) < 10**-7 ):
       _out = copy.deepcopy(self)
       _out.data = np.divide(self.data, other.data)
       return _out
     else:
       ut.exit("ERROR from qmout.py->CUBE: " +\
                "grid mesh does not match")
   else:
     _out = copy.deepcopy(self)
     _out.data = _out.data / other
     return _out
示例#11
0
文件: cube.py 项目: andersx/qctoolkit
    def __init__(self, cube_file=None, **kwargs):
        if cube_file:
            if not os.path.exists(cube_file):
                ut.exit("CUBE file:%s not found" % cube_file)
            self.path, self.name = os.path.split(cube_file)
            if 'format' not in kwargs:
                ext = os.path.splitext(self.name)[1]
                if ext == '.cube':
                    kwargs['format'] = 'cube'
                elif ext == '.casino' or ext == '.dat':
                    kwargs['format'] = 'casino'
                elif self.name == 'CHGCAR' or ext == '.vasp':
                    kwargs['format'] = 'vasp'
                elif ext == '.fchk':
                    kwargs['format'] = 'gaussian'
                else:
                    qtk.exit("unknown extension %s" % ext)
            if kwargs['format'] == 'cube':
                self.data, self.zcoord, self.grid, self.coords\
                  = rq.read_cube(cube_file)
            elif kwargs['format'] == 'vasp':
                self.data, self.zcoord, self.grid = read_vasp(cube_file)
            elif kwargs['format'] == 'casino':
                self.data, self.zcoord, self.grid = read_casino(cube_file)
            elif kwargs['format'] == 'gaussian':
                self.data, self.zcoord, self.grid = \
                  read_gaussian(cube_file, **kwargs)

            self.molecule = qtk.Molecule()
            self.shape = self.data.shape
            self.molecule.R = self.zcoord[:, 1:4] * 0.529177249
            self.molecule.Z = self.zcoord[:, 0]
            self.molecule.N = len(self.zcoord)
            self.molecule.type_list = [ut.Z2n(z) for z in self.molecule.Z]
            self.interp = None

            def vec(i):
                return self.grid[i, 1:]

            self.dV = np.dot(vec(1), np.cross(vec(2), vec(3)))
            self.V = self.dV * self.grid[1, 0] * self.grid[2, 0] * self.grid[3,
                                                                             0]

        else:
            self.grid = np.zeros([4, 4])
            self.molecule = qtk.Molecule()
示例#12
0
  def __init__(self, cube_file = None, **kwargs):
    if cube_file:
      if not os.path.exists(cube_file):
        ut.exit("CUBE file:%s not found" % cube_file)
      self.path, self.name = os.path.split(cube_file)
      if 'format' not in kwargs:
        ext = os.path.splitext(self.name)[1]
        if ext == '.cube':
          kwargs['format'] = 'cube'
        elif ext == '.casino' or ext == '.dat':
          kwargs['format'] = 'casino'
        elif self.name == 'CHGCAR' or ext =='.vasp':
          kwargs['format'] = 'vasp'
        elif ext == '.fchk':
          kwargs['format'] = 'gaussian'
        else:
          qtk.exit("unknown extension %s" % ext)
      if kwargs['format'] == 'cube':
        self.data, self.zcoord, self.grid, self.coords\
          = rq.read_cube(cube_file)
      elif kwargs['format'] == 'vasp':
        self.data, self.zcoord, self.grid = read_vasp(cube_file)
      elif kwargs['format'] == 'casino':
        self.data, self.zcoord, self.grid = read_casino(cube_file)
      elif kwargs['format'] == 'gaussian':
        self.data, self.zcoord, self.grid = \
          read_gaussian(cube_file, **kwargs)

      self.molecule = qtk.Molecule()
      self.shape = self.data.shape
      self.molecule.R = self.zcoord[:,1:4]*0.529177249
      self.molecule.Z = self.zcoord[:,0]
      self.molecule.N = len(self.zcoord)
      self.molecule.type_list = [ut.Z2n(z) for z in self.molecule.Z]
      self.interp = None
  
      def vec(i):
        return self.grid[i,1:]
    
      self.dV = np.dot(vec(1), np.cross(vec(2), vec(3)))
      self.V = self.dV*self.grid[1,0]*self.grid[2,0]*self.grid[3,0]

    else:
      self.grid = np.zeros([4, 4])
      self.molecule = qtk.Molecule()
示例#13
0
def QMRun(inp, program=setting.qmcode, **kwargs):
  """
  interface to run qmcode with written inp files. It manages to start
  qmcode in **cwd**, write to output, collect result, 
  clean up scratch, tmp files according to setup. 
  However, each code require different implementation.

  input:
    inp(str): path to input file
    code(str): qmcode to run, default set to setting.qmcode

  kwargs (optional):
    threads=n(int): number of threads per job
    bigmem=Boolean: big memory request, implemented for CPMD and others

    CPMD:
      save_restart=Boolean
      scr=/path/to/scratch
  """

  if 'threads' in kwargs:
    _threads = kwargs['threads']
  else:
    _threads = 1
  if 'bigmem' in kwargs:
    _bigmem = kwargs['bigmem']
  else:
    if setting.memory > 16:
      _bigmem = True
    else:
      _bigmem = False
  if 'omp' in kwargs:
    omp = kwargs['omp']
  else:
    omp = 1
  if 'save_restart' in kwargs:
    _save_restart = kwargs['save_restart']
  else:
    _save_restart = False
  if 'save_density' in kwargs:
    _save_density = kwargs['save_density']
  else:
    _save_density = False

  if 'chdir' in kwargs and kwargs['chdir']:
    cwd = os.getcwd()
    os.chdir(inp)

  ###########################################
  # SYSTEM CALL SUBPROCESS: Running mpi job #
  ###########################################
  def compute(exestr, outpath, threads_per_job, **kwargs):
    """
    initiate a single MPI job, wait for it, and write to output
    """

    os.environ["OMP_NUM_THREADS"] = str(omp)

    outfile = open(outpath, "w")
    if threads_per_job > 1:
      mpi_cmd = "%s %d"% (setting.mpistr, threads_per_job)
      for mpi_flag in setting.mpi_flags:
        if mpi_flag == '--cpus-per-proc':
          flag = mpi_flag + ' ' + str(threads_per_job)
        else:
          flag = mpi_flag
        mpi_cmd = mpi_cmd + ' ' + flag
      cmd = mpi_cmd + ' ' + exestr
    else:
      cmd = exestr
    ut.progress('QMInp.run', 'running job with command: %s\n' % cmd)
    run = sp.Popen(cmd, shell=True, stdout=outfile)
    # wait each mpijob to finish before lauching another
    # otherwise all mpijobs will be launched simutaniously
    run.wait()
    outfile.close()
  ########## END OF SYSTEM CALL ##########

  #######################
  # CPMD IMPLEMENTATION #
  #######################
  if program.lower() == 'cpmd':
    if 'exe' in kwargs:
      exe = kwargs['exe']
    else:
      exe = setting.cpmd_exe

    if 'scr' in kwargs and kwargs['scr']:
        scrdir = kwargs['scr']
        ut.delete(inpname, 'FILEPATH', 2)
        ut.insert(inpname, 'CPMD', ' FILEPATH\n  %s' % scrdir)

    inp_list = sorted(glob.glob('*.inp'))
    for job in inp_list:
      out = os.path.splitext(job)[0] + '.out'
      exestr = "%s %s" % (exe, job)
      compute(exestr, out, _threads)
      rst_list = sorted(glob.glob('RESTART.*'))
      if rst_list:
        rst_n = rst_list[-1]
        if os.path.exists('RESTART'):
          os.remove('RESTART')
        os.link(rst_n, 'RESTART')
    final_out = re.sub(r'_[0-9][0-9].out$', '.out', out)
    if final_out != out:
      os.copy(out, final_out)

    # clean up files
    files = glob.glob('*')
    tmp = filter(\
      lambda x: '.out' not in x \
                and '.inp' not in x\
                and '.psp' not in x\
                and '.xyz' not in x\
                and 'KPTS_GENERATION' not in x\
                and 'RESTART' not in x\
                and 'DENSITY' not in x\
                and 'SPINDEN' not in x, files
    )
    for f in tmp: os.remove(f)
    if not _save_restart:
      rst_list = glob.glob("RESTART*")
      for rfile in rst_list:
        os.remove(rfile)

    densities = glob.glob('*DEN*')
    for i in range(len(densities)):
      exe = setting.cpmd_cpmd2cube_exe
      log_name = densities[i] + '_%02d.log' % i
      log = open(log_name, 'w')
      run = sp.Popen("%s -fullmesh %s" % (exe, densities[i]), 
               shell=True,
               stdout=log)
      run.wait()
      log.close()
  
    if os.path.exists(out):
      qio_out = qio.QMOut(out, program='cpmd')
    else:
      qio_out = None

  #######################
  # VASP IMPLEMENTATION #
  #######################
  elif program.lower() == 'vasp':
    if 'exe' in kwargs:
      exestr = kwargs['exe']
    else:
      exestr = setting.vasp_exe
    qmoutput = inp + '.out'
    qmlog = inp + '.log'
    compute(exestr, qmoutput, _threads)
    qio_out = qio.QMOut('vasprun.xml', program='vasp')

    if not _save_restart:
      try:
        os.remove('WAVECAR')
      except:
        pass
    try:
      os.remove('POTCAR')
    except:
      pass

    os.rename(qmoutput, qmlog)
    shutil.copyfile('vasprun.xml', qmoutput)

  #########################
  # NWChem IMPLEMENTATION #
  #########################
  elif program.lower() == 'nwchem':
    if 'exe' in kwargs:
      exe = kwargs['exe']
    else:
      exe = setting.nwchem_exe
    exestr = "%s %s" % (exe, inp)
    qmoutput = os.path.splitext(inp)[0] + '.out'
    compute(exestr, qmoutput, _threads)
    qio_out = qio.QMOut(qmoutput, program='nwchem')

    files = glob.glob('*.*')
    tmp = filter(\
      lambda x: '.out' not in x \
                and '.inp' not in x\
                and '.cube' not in x\
                and '.movecs' not in x, files
    )
    for f in tmp: os.remove(f)
    movecs = glob.glob('*.movecs')
    for f in movecs:
      exe = setting.nwchem_mov2asc_exe
      nb = qio_out.n_basis
      out = re.sub('\.movecs','.modat',f)
      exestr = "%s %d %s %s" % (exe, nb, f, out)
      run = sp.Popen(exestr, shell=True)
      run.wait()
      qio_out.getMO(out)
      if not _save_restart:
        os.remove(f)

  #########################
  # BigDFT IMPLEMENTATION #
  #########################
  elif program.lower() == 'bigdft':
    if 'exe' in kwargs:
      exe = kwargs['exe']
    else:
      exe = setting.bigdft_exe
    inp = os.path.splitext(inp)[0]
    exestr = "%s %s" % (exe, inp)
    qmoutput = inp + '.out'
    compute(exestr, qmoutput, _threads)
    qio_out = qio.QMOut(qmoutput, program='bigdft')

  #########################
  # Abinit IMPLEMENTATION #
  #########################
  elif program.lower() == 'abinit':
    if 'exe' in kwargs:
      exe = kwargs['exe']
    else:
      exe = setting.abinit_exe
    inp = os.path.splitext(inp)[0]
    exestr = "%s < %s" % (exe, inp + '.files')
    qmlog = inp + '.log'
    qmoutput = inp + '.out'
    compute(exestr, qmlog, _threads)
    qio_out = qio.QMOut(qmoutput, program='abinit')

    # clean up files
    files = glob.glob('*')
    tmp = filter(\
      lambda x: '.out' not in x \
                and '.log' not in x\
                and '.inp' not in x\
                and '.files' not in x\
                and 'psp' not in x\
                and '_EIG' not in x\
                and '_WFK' not in x\
                and '_DEN' not in x, files
    )
    for f in tmp: os.remove(f)
    if not _save_restart:
      for rst in glob.glob('*_WFK'):
        os.remove(rst)
    if not _save_density:
      for den in glob.glob('*_DEN'):
        os.remove(den)

  #############################
  # Gaussian09 IMPLEMENTATION #
  #############################
  elif program.lower() == 'gaussian':
    if 'exe' in kwargs:
      exe = kwargs['exe']
    else:
      exe = setting.gaussian_exe

    exestr = "%s %s" % (exe, inp)
    qmoutput = os.path.splitext(inp)[0] + '.out'
    qmlog = os.path.splitext(inp)[0] + '.log'
    compute(exestr, qmoutput, _threads)
    os.rename(qmlog, qmoutput)

    chks = glob.glob('*.chk')
    for chk in chks:
      exe = setting.gaussian_formchk_exe
      exestr = "%s %s" % (exe, chk)
      run = sp.Popen(exestr, shell=True)
      run.wait()

    qio_out = qio.QMOut(qmoutput, program='gaussian')

  ##################################
  # QuantumESPRESSO IMPLEMENTATION #
  ##################################
  elif program.lower() == 'espresso':
    if 'exe' in kwargs:
      exe = kwargs['exe']
    else:
      exe = setting.espresso_exe

    inp_list = sorted(glob.glob('*.inp'))
    for job in inp_list:
      out = os.path.splitext(job)[0] + '.out'
      exestr = "%s < %s" % (exe, job)
      compute(exestr, out, _threads)
    qio_out = qio.QMOut(out, program='espresso')
    if not _save_restart:
      rst_list = glob.glob("*.wfc*")
      rst_list.extend(glob.glob("*.restart_*"))
    else:
      rst_list = []
    for r in rst_list:
      os.remove(r)
      
  #########################
  # GAMESS IMPLEMENTATION #
  #########################
  elif program.lower() == 'gamess':
    ut.exit("ERROR! program '%s' not implemented" % program)
  # and others... #

  else: 
    ut.exit("ERROR! program '%s' not recognized" % program)

  if 'cwd' in locals():
    os.chdir(cwd)
  return qio_out
示例#14
0
def QMRun(inp, program=setting.qmcode, **kwargs):
    """
  interface to run qmcode with written inp files. It manages to start
  qmcode in **cwd**, write to output, collect result, 
  clean up scratch, tmp files according to setup. 
  However, each code require different implementation.

  input:
    inp(str): path to input file
    code(str): qmcode to run, default set to setting.qmcode

  kwargs (optional):
    threads=n(int): number of threads per job
    bigmem=Boolean: big memory request, implemented for CPMD and others

    CPMD:
      save_restart=Boolean
      scr=/path/to/scratch
  """

    if 'threads' in kwargs:
        _threads = kwargs['threads']
    else:
        _threads = 1
    if 'bigmem' in kwargs:
        _bigmem = kwargs['bigmem']
    else:
        if setting.memory > 16:
            _bigmem = True
        else:
            _bigmem = False
    if 'omp' in kwargs:
        omp = kwargs['omp']
    else:
        omp = 1
    if 'save_restart' in kwargs:
        _save_restart = kwargs['save_restart']
    else:
        _save_restart = False
    if 'save_density' in kwargs:
        _save_density = kwargs['save_density']
    else:
        _save_density = False

    if 'chdir' in kwargs and kwargs['chdir']\
    or 'run_dir' in kwargs and kwargs['run_dir']:
        dest_dir = os.path.splitext(inp)[0]
        cwd = os.getcwd()
        os.chdir(dest_dir)

    ###########################################
    # SYSTEM CALL SUBPROCESS: Running mpi job #
    ###########################################
    def compute(exestr, outpath, threads_per_job, **kwargs):
        """
    initiate a single MPI job, wait for it, and write to output
    """

        os.environ["OMP_NUM_THREADS"] = str(omp)

        outfile = open(outpath, "w")
        if threads_per_job > 1:
            mpi_cmd = "%s %d" % (setting.mpistr, threads_per_job)
            for mpi_flag in setting.mpi_flags:
                if mpi_flag == '--cpus-per-proc':
                    flag = mpi_flag + ' ' + str(threads_per_job)
                else:
                    flag = mpi_flag
                mpi_cmd = mpi_cmd + ' ' + flag
            cmd = mpi_cmd + ' ' + exestr
        else:
            cmd = exestr
        ut.progress('QMInp.run', 'running job with command: %s\n' % cmd)
        if 'env' in kwargs:
            run = sp.Popen(cmd, shell=True, stdout=outfile, env=kwargs['env'])
        else:
            run = sp.Popen(cmd, shell=True, stdout=outfile)
        # wait each mpijob to finish before lauching another
        # otherwise all mpijobs will be launched simutaniously
        run.wait()
        outfile.close()

    ########## END OF SYSTEM CALL ##########

    #################################
    # SYSTEM CALL for post analysis #
    #################################
    def sys_run(cmd_str, log_file=None):
        if log_file:
            log = open(log_file, 'w')
        try:
            qtk.progress("QMRun", cmd_str)
            if log_file:
                run = sp.Popen(cmd_str, shell=True, stdout=log)
            else:
                run = sp.Popen(cmd_str, shell=True)
            run.wait()
        except Exception as err:
            qtk.warning('%s failed with error: %s' % (cmd_str, err))
        if log_file:
            log.close()

    ########## END OF SYSTEM CALL ##########

    #######################
    # CPMD IMPLEMENTATION #
    #######################
    if program.lower() == 'cpmd':
        if 'exe' in kwargs:
            exe = kwargs['exe']
        else:
            exe = setting.cpmd_exe

        if 'scr' in kwargs and kwargs['scr']:
            scrdir = kwargs['scr']
            ut.delete(inpname, 'FILEPATH', 2)
            ut.insert(inpname, 'CPMD', ' FILEPATH\n  %s' % scrdir)

        inp_list = sorted(glob.glob('*.inp'))
        for job in inp_list:
            out = os.path.splitext(job)[0] + '.out'
            exestr = "%s %s" % (exe, job)
            compute(exestr, out, _threads)
            if (len(inp_list) > 1):
                rst_list = sorted(glob.glob('RESTART.*'))
                if rst_list:
                    rst_n = rst_list[-1]
                    if os.path.exists('RESTART'):
                        os.remove('RESTART')
                    os.link(rst_n, 'RESTART')
        final_out = re.sub(r'_[0-9][0-9].out$', '.out', out)
        if final_out != out:
            os.copy(out, final_out)

        # clean up files
        files = sorted(glob.glob('*'))
        tmp = filter(\
          lambda x: '.out' not in x \
                    and '.inp' not in x\
                    and '.psp' not in x\
                    and '.xyz' not in x\
                    and 'KPTS_GENERATION' not in x\
                    and 'RESTART' not in x\
                    and 'DENSITY' not in x\
                    and 'SPINDEN' not in x, files
        )
        for f in tmp:
            os.remove(f)
        if not _save_restart:
            rst_list = sorted(glob.glob("RESTART*"))
            for rfile in rst_list:
                os.remove(rfile)

        densities = sorted(glob.glob('*DEN*'))
        for i in range(len(densities)):
            exe = setting.cpmd_cpmd2cube_exe
            cmd = "%s -fullmesh %s" % (exe, densities[i])
            log_name = densities[i] + '_%02d.log' % i
            sys_run(cmd, log_name)
            #log = open(log_name, 'w')
            #try:
            #  run = sp.Popen("%s -fullmesh %s" % (exe, densities[i]),
            #           shell=True,
            #           stdout=log)
            #  run.wait()
            #except Exception as err:
            #  qtk.warning('%s failed with error: %s' % (exe, err))
            #log.close()

        if os.path.exists(out):
            qio_out = qio.QMOut(out, program='cpmd')
        else:
            qio_out = None

    #######################
    # VASP IMPLEMENTATION #
    #######################
    elif program.lower() == 'vasp':
        if 'exe' in kwargs:
            exestr = kwargs['exe']
        else:
            exestr = setting.vasp_exe
        qmoutput = inp + '.out'
        qmlog = inp + '.log'
        compute(exestr, qmoutput, _threads)
        qio_out = qio.QMOut('vasprun.xml', program='vasp')

        if not _save_restart:
            try:
                os.remove('WAVECAR')
            except:
                pass
        try:
            os.remove('POTCAR')
        except:
            pass

        os.rename(qmoutput, qmlog)
        shutil.copyfile('vasprun.xml', qmoutput)

    #########################
    # NWChem IMPLEMENTATION #
    #########################
    elif program.lower() == 'nwchem':
        if 'exe' in kwargs:
            exe = kwargs['exe']
        else:
            exe = setting.nwchem_exe
        exestr = "%s %s" % (exe, inp)
        qmoutput = os.path.splitext(inp)[0] + '.out'
        compute(exestr, qmoutput, _threads)
        qio_out = qio.QMOut(qmoutput, program='nwchem')

        files = sorted(glob.glob('*.*'))
        tmp = filter(\
          lambda x: '.out' not in x \
                    and '.inp' not in x\
                    and '.cube' not in x\
                    and '.movecs' not in x, files
        )
        for f in tmp:
            os.remove(f)
        movecs = sorted(glob.glob('*.movecs'))
        for f in movecs:
            exe = setting.nwchem_mov2asc_exe
            nb = qio_out.n_basis
            out = re.sub('\.movecs', '.modat', f)
            exestr = "%s %d %s %s" % (exe, nb, f, out)
            sys_run(exestr)
            #try:
            #  run = sp.Popen(exestr, shell=True)
            #  run.wait()
            #  qio_out.getMO(out)
            #except Exception as err:
            #  qtk.warning('%s failed with error: %s' % (exe, err))
            if not _save_restart:
                os.remove(f)

    #########################
    # BigDFT IMPLEMENTATION #
    #########################
    elif program.lower() == 'bigdft':
        if 'exe' in kwargs:
            exe = kwargs['exe']
        else:
            exe = setting.bigdft_exe
        env = os.environ.copy()
        inp = os.path.splitext(inp)[0]
        exestr = "%s %s" % (exe, inp)
        qmoutput = inp + '.out'
        qmlog = 'log-%s.yaml' % inp
        compute(exestr, qmoutput, _threads, env=env)
        qio_out = qio.QMOut(qmlog, program='bigdft')

    #########################
    # Abinit IMPLEMENTATION #
    #########################
    elif program.lower() == 'abinit':
        if 'exe' in kwargs:
            exe = kwargs['exe']
        else:
            exe = setting.abinit_exe
        inp = os.path.splitext(inp)[0]
        exestr = "%s < %s" % (exe, inp + '.files')
        qmlog = inp + '.log'
        qmoutput = inp + '.out'
        compute(exestr, qmlog, _threads)

        # unfold bandstructure
        if 'unfold' in kwargs and kwargs['unfold']:
            folds = kwargs['unfold']
            exe = setting.abinit_f2b_exe
            wfk_list = sorted(glob.glob("*_WFK"))
            if len(wfk_list) > 0:
                wfk = wfk_list[-1]
                qtk.progress("QMRun",
                             "linking wfk file %s to unfold_WFK" % wfk)
                os.link(wfk, 'unfold_WFK')
                wfk_root = wfk.replace('_WFK', '')
                log_name = '%s_f2b.log' % wfk_root
                fold_str = [str(f) for f in folds]
                cmd_str = "%s unfold_WFK %s" % (exe, ':'.join(fold_str))
                sys_run(cmd_str, log_name)
                qtk.progress("QMRun", "Done, remove unfold_WFK")
                os.remove('unfold_WFK')
                #try:
                #  qtk.progress("QMRun", cmd_str)
                #  run = sp.Popen(cmd_str, shell=True, stdout=log)
                #  run.wait()
                #except Exception as err:
                #  qtk.warning('%s failed with error: %s' % (exe, err))
                #log.close()
            else:
                qtk.warning('unfolding but no wavefunction file found...')

            if 'unfold_cleanup' in kwargs and kwargs['unfold_cleanup']:
                qtk.progress("QMRun", "deleting all WFK files")
                for wfk in sorted(glob.glob("*_WFK")):
                    os.remove(wfk)

        # clean up files
        files = sorted(glob.glob('*'))
        tmp = filter(\
          lambda x: '.out' not in x \
                    and '.f2b' not in x\
                    and '.log' not in x\
                    and '.inp' not in x\
                    and '.files' not in x\
                    and 'psp' not in x\
                    and '_EIG' not in x\
                    and '_WFK' not in x\
                    and '_DOS' not in x\
                    and '_DEN' not in x, files
        )
        for f in tmp:
            os.remove(f)
        if not _save_restart:
            for rst in sorted(glob.glob('*_WFK')):
                os.remove(rst)
        if not _save_density:
            for den in sorted(glob.glob('*_DEN')):
                os.remove(den)

        densities = sorted(glob.glob('*_DEN'))
        if len(densities) > 0:
            i = len(densities) - 1
            exe = setting.abinit_cut3d_exe
            #den_inp = densities[i] + '.cov'
            den_inp = densities[-1] + '.cov'
            cube_file = inp + '.cube'
            den_inp_file = open(den_inp, 'wb')
            den_inp_file.write("%s\n14\n%s\n0" % (densities[i], cube_file))
            den_inp_file.close()
            log_name = densities[i] + '.log'
            cmd = "%s < %s" % (exe, den_inp)
            sys_run(cmd, log_name)
            #log = open(log_name, 'w')
            #try:
            #  run = sp.Popen("%s < %s" % (exe, den_inp),
            #           shell=True,
            #           stdout=log)
            #  run.wait()
            #except Exception as err:
            #  qtk.warning('%s failed with error: %s' % (exe, err))
            #log.close()

        qio_out = qtk.QMOut(qmoutput, program='abinit')

    #############################
    # Gaussian09 IMPLEMENTATION #
    #############################
    elif program.lower() == 'gaussian':
        if 'exe' in kwargs:
            exe = kwargs['exe']
        else:
            exe = setting.gaussian_exe

        exestr = "%s %s" % (exe, inp)
        qmoutput = os.path.splitext(inp)[0] + '.out'
        qmlog = os.path.splitext(inp)[0] + '.log'
        compute(exestr, qmoutput, _threads)
        os.rename(qmlog, qmoutput)

        chks = sorted(glob.glob('*.chk'))
        for chk in chks:
            exe = setting.gaussian_formchk_exe
            exestr = "%s %s" % (exe, chk)
            sys_run(exestr)
            #run = sp.Popen(exestr, shell=True)
            #run.wait()
        if _save_density:
            fchk = sorted(glob.glob("*.fchk"))[-1]
            q = qtk.CUBE(fchk)

        qio_out = qio.QMOut(qmoutput, program='gaussian')

    ##################################
    # QuantumESPRESSO IMPLEMENTATION #
    ##################################
    elif program.lower() == 'espresso':
        if 'exe' in kwargs:
            exe = kwargs['exe']
        else:
            exe = setting.espresso_exe

        inp_list = sorted(glob.glob('*.inp'))
        for job in inp_list:
            out = os.path.splitext(job)[0] + '.out'
            exestr = "%s < %s" % (exe, job)
            compute(exestr, out, _threads)
        qio_out = qio.QMOut(out, program='espresso')
        if not _save_restart:
            rst_list = sorted(glob.glob("*.wfc*"))
            rst_list.extend(sorted(glob.glob("*.restart_*")))
        else:
            rst_list = []
        for r in rst_list:
            os.remove(r)

    #########################
    # GAMESS IMPLEMENTATION #
    #########################
    elif program.lower() == 'gamess':
        ut.exit("ERROR! program '%s' not implemented" % program)
    # and others... #

    else:
        ut.exit("ERROR! program '%s' not recognized" % program)

    if 'cwd' in locals():
        os.chdir(cwd)

    qio_out.path = inp
    return qio_out