Пример #1
0
def main():
    args = parse_args()

    fn_h5, grp_name = parse_h5(args.output, 'output')
    # check if the group is already present (and not empty) in the output file
    if check_output(fn_h5, grp_name, args.overwrite):
        return

    # Load the system
    sys = System.from_file(args.wfn)

    # Define a list of optional arguments for the WPartClass:
    WPartClass = wpart_schemes[args.scheme]
    kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in WPartClass.options)

    # Load the proatomdb
    if args.atoms is not None:
        proatomdb = ProAtomDB.from_file(args.atoms)
        proatomdb.normalize()
        kwargs['proatomdb'] = proatomdb
    else:
        proatomdb = None

    # Run the partitioning
    agspec = AtomicGridSpec(args.grid)
    molgrid = BeckeMolGrid(sys, agspec, mode='only')
    sys.update_grid(molgrid) # for the grid to be written to the output
    wpart = wpart_schemes[args.scheme](sys, molgrid, **kwargs)
    names = wpart.do_all()

    write_part_output(fn_h5, grp_name, wpart, names, args)
Пример #2
0
def main():
    args = parse_args()

    fn_h5, grp_name = parse_h5(args.output, 'output')
    # check if the group is already present (and not empty) in the output file
    if check_output(fn_h5, grp_name, args.overwrite):
        return

    # Load the system
    sys = System.from_file(args.cube)
    ugrid = sys.grid
    if not isinstance(ugrid, UniformGrid):
        raise TypeError(
            'The specified file does not contain data on a rectangular grid.')
    ugrid.pbc[:] = parse_pbc(args.pbc)
    moldens = sys.extra['cube_data']

    # Reduce the grid if required
    if args.stride > 1 or args.chop > 0:
        moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop)

    # Load the proatomdb and make pro-atoms more compact if that is requested
    proatomdb = ProAtomDB.from_file(args.atoms)
    if args.compact is not None:
        proatomdb.compact(args.compact)
    proatomdb.normalize()

    # Select the partitioning scheme
    CPartClass = cpart_schemes[args.scheme]

    # List of element numbers for which weight corrections are needed:
    wcor_numbers = list(iter_elements(args.wcor))

    # Run the partitioning
    kwargs = dict((key, val) for key, val in vars(args).iteritems()
                  if key in CPartClass.options)
    cpart = cpart_schemes[args.scheme](sys, ugrid, True, moldens, proatomdb,
                                       wcor_numbers, args.wcor_rcut_max,
                                       args.wcor_rcond, **kwargs)
    names = cpart.do_all()

    # Do a symmetry analysis if requested.
    if args.symmetry is not None:
        sys_sym = System.from_file(args.symmetry)
        sym = sys_sym.extra.get('symmetry')
        if sym is None:
            raise ValueError('No symmetry information found in %s.' %
                             args.symmetry)
        sys_results = dict((name, cpart[name]) for name in names)
        sym_results = symmetry_analysis(sys, sym, sys_results)
        cpart.cache.dump('symmetry', sym_results)
        names.append('symmetry')
        sys.extra['symmetry'] = sym

    write_part_output(fn_h5, grp_name, cpart, names, args)
Пример #3
0
def main():
    args = parse_args()

    fn_h5, grp_name = parse_h5(args.output, 'output')
    # check if the group is already present (and not empty) in the output file
    if check_output(fn_h5, grp_name, args.overwrite):
        return

    # Load the system
    sys = System.from_file(args.cube)
    ugrid = sys.grid
    if not isinstance(ugrid, UniformGrid):
        raise TypeError('The specified file does not contain data on a rectangular grid.')
    ugrid.pbc[:] = parse_pbc(args.pbc)
    moldens = sys.extra['cube_data']

    # Reduce the grid if required
    if args.stride > 1 or args.chop > 0:
        moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop)

    # Load the proatomdb and make pro-atoms more compact if that is requested
    proatomdb = ProAtomDB.from_file(args.atoms)
    if args.compact is not None:
        proatomdb.compact(args.compact)
    proatomdb.normalize()

    # Select the partitioning scheme
    CPartClass = cpart_schemes[args.scheme]

    # List of element numbers for which weight corrections are needed:
    wcor_numbers = list(iter_elements(args.wcor))

    # Run the partitioning
    kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options)
    cpart = cpart_schemes[args.scheme](
        sys, ugrid, True, moldens, proatomdb, wcor_numbers,
        args.wcor_rcut_max, args.wcor_rcond, **kwargs)
    names = cpart.do_all()

    # Do a symmetry analysis if requested.
    if args.symmetry is not None:
        sys_sym = System.from_file(args.symmetry)
        sym = sys_sym.extra.get('symmetry')
        if sym is None:
            raise ValueError('No symmetry information found in %s.' % args.symmetry)
        sys_results = dict((name, cpart[name]) for name in names)
        sym_results = symmetry_analysis(sys, sym, sys_results)
        cpart.cache.dump('symmetry', sym_results)
        names.append('symmetry')
        sys.extra['symmetry'] = sym

    write_part_output(fn_h5, grp_name, cpart, names, args)
Пример #4
0
def main():
    args = parse_args()

    fn_h5, grp_name = parse_h5(args.output, 'output')
    # check if the group is already present (and not empty) in the output file
    if check_output(fn_h5, grp_name, args.overwrite):
        return

    # Load the system
    mol = IOData.from_file(args.wfn)

    # Define a list of optional arguments for the WPartClass:
    WPartClass = wpart_schemes[args.scheme]
    kwargs = dict((key, val) for key, val in vars(args).iteritems()
                  if key in WPartClass.options)

    # Load the proatomdb
    if args.atoms is not None:
        proatomdb = ProAtomDB.from_file(args.atoms)
        proatomdb.normalize()
        kwargs['proatomdb'] = proatomdb
    else:
        proatomdb = None

    # Run the partitioning
    agspec = AtomicGridSpec(args.grid)
    grid = BeckeMolGrid(mol.coordinates,
                        mol.numbers,
                        mol.pseudo_numbers,
                        agspec,
                        mode='only')
    dm_full = mol.get_dm_full()
    moldens = mol.obasis.compute_grid_density_dm(dm_full,
                                                 grid.points,
                                                 epsilon=args.epsilon)
    dm_spin = mol.get_dm_spin()
    if dm_spin is not None:
        kwargs['spindens'] = mol.obasis.compute_grid_density_dm(
            dm_spin, grid.points, epsilon=args.epsilon)
    wpart = wpart_schemes[args.scheme](mol.coordinates, mol.numbers,
                                       mol.pseudo_numbers, grid, moldens,
                                       **kwargs)
    keys = wpart.do_all()

    if args.slow:
        # ugly hack for the slow analysis involving the AIM overlap operators.
        wpart_slow_analysis(wpart, mol)
        keys = list(wpart.cache.iterkeys(tags='o'))

    write_part_output(fn_h5, grp_name, wpart, keys, args)
Пример #5
0
def _get_eos(filename, scheme):
    # build proatom database
    atoms = glob.glob('chemtools/data/atom_0*')
    proatomdb = ProAtomDB.from_files(atoms, "power:5e-8:20:40:146")
    # load molecule & make grid, denspart, and eos instances
    with path('chemtools.data', filename) as file_path:
        mol = Molecule.from_file(file_path)
    grid = MolecularGrid.from_molecule(mol,
                                       specs='power:5e-8:20:40:146',
                                       k=4,
                                       rotate=False)
    part = DensPart.from_molecule(mol,
                                  scheme=scheme,
                                  grid=grid,
                                  local=False,
                                  proatomdb=proatomdb)
    return EOS(mol, part)
Пример #6
0
    def __init__(self, coordinates, numbers, pseudo_numbers, density, grid, scheme="h", **kwargs):

        wpart = wpart_schemes[scheme]
        # make proatom database
        if scheme.lower() not in ["mbis", "b"]:
            if "proatomdb" not in kwargs.keys():
                proatomdb = ProAtomDB.from_refatoms(numbers)
            kwargs["proatomdb"] = proatomdb
        # partition
        self.part = wpart(coordinates, numbers, pseudo_numbers, grid, density, **kwargs)
        self.part.do_all()

        self.grid = grid
        self.density = density
        self.coordines = coordinates
        self.numbers = numbers
        self.pseudo_numbers = pseudo_numbers
        self.charges = self.part['charges']
Пример #7
0
    def __init__(self,
                 coordinates,
                 numbers,
                 pseudo_numbers,
                 density,
                 grid,
                 scheme="h",
                 **kwargs):
        """Initialize class.

        Parameters
        ----------
        coordinates : np.ndarray, shape=(M, 3)
            Cartesian coordinates of `M` atoms in the molecule.
        numbers : np.ndarray, shape=(M,)
            Atomic number of `M` atoms in the molecule.
        pseudo_numbers : np.ndarray, shape=(M,)
            Pseudo-number of `M` atoms in the molecule.
        density : np.ndarray, shape=(N,)
            Total density to be partitioned.
        grid : BeckeMolGrid
            Instance of BeckeMolGrid numerical integration grid.
        scheme : str
            Type of atoms-in-molecule partitioning scheme.

        """
        wpart = wpart_schemes[scheme]
        # make proatom database
        if scheme.lower() not in ["mbis", "b"]:
            if "proatomdb" not in kwargs.keys():
                proatomdb = ProAtomDB.from_refatoms(numbers)
                kwargs["proatomdb"] = proatomdb
            kwargs["local"] = False
        # partition
        self.part = wpart(coordinates, numbers, pseudo_numbers, grid, density,
                          **kwargs)
        self.part.do_charges()

        self.grid = grid
        self.density = density
        self.coordines = coordinates
        self.numbers = numbers
        self.pseudo_numbers = pseudo_numbers
        self.charges = self.part['charges']
Пример #8
0
def main():
    args = parse_args()

    fn_h5, grp_name = parse_h5(args.output, 'output')
    # check if the group is already present (and not empty) in the output file
    if check_output(fn_h5, grp_name, args.overwrite):
        return

    # Load the system
    mol = IOData.from_file(args.wfn)

    # Define a list of optional arguments for the WPartClass:
    WPartClass = wpart_schemes[args.scheme]
    kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in WPartClass.options)

    # Load the proatomdb
    if args.atoms is not None:
        proatomdb = ProAtomDB.from_file(args.atoms)
        proatomdb.normalize()
        kwargs['proatomdb'] = proatomdb
    else:
        proatomdb = None

    # Run the partitioning
    agspec = AtomicGridSpec(args.grid)
    grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, agspec, mode='only')
    dm_full = mol.get_dm_full()
    moldens = mol.obasis.compute_grid_density_dm(dm_full, grid.points, epsilon=args.epsilon)
    dm_spin = mol.get_dm_spin()
    if dm_spin is not None:
        kwargs['spindens'] = mol.obasis.compute_grid_density_dm(dm_spin, grid.points, epsilon=args.epsilon)
    wpart = wpart_schemes[args.scheme](mol.coordinates, mol.numbers, mol.pseudo_numbers,grid, moldens, **kwargs)
    keys = wpart.do_all()

    if args.slow:
        # ugly hack for the slow analysis involving the AIM overlap operators.
        wpart_slow_analysis(wpart, mol)
        keys = list(wpart.cache.iterkeys(tags='o'))

    write_part_output(fn_h5, grp_name, wpart, keys, args)
Пример #9
0
def main():
    args = parse_args()

    fn_h5, grp_name = parse_h5(args.output, 'output')
    # check if the group is already present (and not empty) in the output file
    if check_output(fn_h5, grp_name, args.overwrite):
        return

    # Load the IOData
    mol = IOData.from_file(args.cube)
    ugrid = mol.grid
    if not isinstance(ugrid, UniformGrid):
        raise TypeError('The density cube file does not contain data on a rectangular grid.')
    ugrid.pbc[:] = parse_pbc(args.pbc)
    moldens = mol.cube_data

    # Reduce the grid if required
    if args.stride > 1 or args.chop > 0:
        moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop)

    # Load the spin density (optional)
    if args.spindens is not None:
        molspin = IOData.from_file(args.spindens)
        if not isinstance(molspin.grid, UniformGrid):
            raise TypeError('The spin cube file does not contain data on a rectangular grid.')
        spindens = molspin.cube_data
        if args.stride > 1 or args.chop > 0:
            spindens = reduce_data(spindens, molspin.grid, args.stride, args.chop)[0]
        if spindens.shape != moldens.shape:
            raise TypeError('The shape of the spin cube does not match the shape of the density cube.')
    else:
        spindens = None

    # Load the proatomdb and make pro-atoms more compact if that is requested
    proatomdb = ProAtomDB.from_file(args.atoms)
    if args.compact is not None:
        proatomdb.compact(args.compact)
    proatomdb.normalize()

    # Select the partitioning scheme
    CPartClass = cpart_schemes[args.scheme]

    # List of element numbers for which weight corrections are needed:
    if args.wcor == '0':
        wcor_numbers = []
    else:
        wcor_numbers = list(iter_elements(args.wcor))

    # Run the partitioning
    kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options)
    cpart = cpart_schemes[args.scheme](
        mol.coordinates, mol.numbers, mol.pseudo_numbers, ugrid, moldens,
        proatomdb, spindens=spindens, local=True, wcor_numbers=wcor_numbers,
        wcor_rcut_max=args.wcor_rcut_max, wcor_rcond=args.wcor_rcond, **kwargs)
    keys = cpart.do_all()

    # Do a symmetry analysis if requested.
    if args.symmetry is not None:
        mol_sym = IOData.from_file(args.symmetry)
        if not hasattr(mol_sym, 'symmetry'):
            raise ValueError('No symmetry information found in %s.' % args.symmetry)
        aim_results = dict((key, cpart[key]) for key in keys)
        sym_results = symmetry_analysis(mol.coordinates, ugrid.get_cell(), mol_sym.symmetry, aim_results)
        cpart.cache.dump('symmetry', sym_results)
        keys.append('symmetry')

    write_part_output(fn_h5, grp_name, cpart, keys, args)
Пример #10
0
def get_proatomdb_hf_lan():
    '''Return a proatomdb of H, O, Si at hf/LANL2MB for testing purposes'''
    fns = glob(context.get_fn('test/atom_???_???_hf_lan.fchk'))
    return ProAtomDB.from_files(fns)
Пример #11
0
def get_proatomdb_hf_sto3g():
    '''Return a proatomdb of H and O at hf/sto-3g for testing purposes'''
    fns = glob(context.get_fn('test/atom_???_???_hf_sto3g.fchk'))
    return ProAtomDB.from_files(fns)
Пример #12
0
def get_proatomdb_cp2k():
    '''Return a proatomdb of pseudo oxygens and one silicon for testing purposes'''
    fns = glob(context.get_fn('test/atom_*.cp2k.out'))
    return ProAtomDB.from_files(fns)
Пример #13
0
def main_convert(args):
    # The atomic grid specification
    agspec = AtomicGridSpec(args.grid)

    # The program is detected based on the run script that is present
    run_scripts = glob("run_*.sh")
    if len(run_scripts) != 1:
        raise RuntimeError(
            'Found %i run_*.sh scripts while exactly one is needed to know which program was used to run the atomic computations.'
            % len(run_scripts))
    program = atom_programs[run_scripts[0][4:-3]]

    # Loop over all sensible directories
    energy_table = EnergyTable()
    records = []
    for dn_state in sorted(glob("[01]??_??_[01]??_q[+-]??")):
        number = int(dn_state[:3])
        pop = int(dn_state[7:10])

        cases = []
        for dn_mult in sorted(glob('%s/mult??' % dn_state)):
            if log.do_medium:
                log('Loading from', dn_mult)
            data, energy = program.load_atom(dn_mult)
            if energy is None:
                if log.do_medium:
                    log('No (sensible) results found:  ', dn_mult)
                continue
            cases.append((energy, data))

        if len(cases) == 0:
            if log.do_medium:
                log('Nothing found in:  ', dn_state)
            continue

        # Get the lowest in energy and write to chk file
        cases.sort()
        energy, data = cases[0]

        # Add case to energy table
        energy_table.add(number, pop, energy)

        # Write atom to HORTON file if possible
        if data is not None:
            data.to_file('%s/horton.h5' % dn_state)

        # Construct a record for the proatomdb
        records.append(ProAtomRecord.from_iodata(data, agspec))

        # Release memory
        data = None
        del cases

        # Let user know we are alive.
        if log.do_medium:
            log('Succesfull:        ', dn_state)

    # Report energies
    if log.do_medium:
        energy_table.log()

    # Write out atoms file
    proatomdb = ProAtomDB(records)
    proatomdb.to_file('atoms.h5')
    if log.do_medium:
        log('Written atoms.h5')

    # Make nice figures
    plot_atoms(proatomdb)
Пример #14
0
def get_dict_population(molecule, approach, scheme, **kwargs):
    r"""Return dictionary of number of electrons and corresponding atomic charges values.

    Parameters
    ----------
    molecule : Molecule or Sequence of Molecule
        Instance of Molecule class, or sequence of Molecule class instances.
    approach : str, optional
        Choose between "FMR" (fragment of molecular response) or "RMF"
        (response of molecular fragment).
    scheme : str
        Partitioning scheme.
    kwargs : optional
    """
    # check approach
    if approach.lower() not in ["rmf", "fmr"]:
        raise ValueError("Argument approach={0} is not valid.".format(approach))

    # case of populations available in molecule
    if scheme.lower() not in wpart_schemes:
        # check approach & molecule instances
        if approach.lower() != "rmf":
            raise ValueError("Condensing with scheme={0} is only possible in combination with "
                             "approach='RMF'! Given approach={1}".format(scheme, approach))
        if (not hasattr(type(molecule), "__iter__") or len(molecule) != 3 or not
                np.all([isinstance(mol, Molecule) for mol in molecule])):
            raise ValueError("Condensing with scheme={0} needs 3 molecules!".format(scheme))
        # get populations
        pops = [getattr(mol, scheme + "_charges") for mol in molecule]
        if np.any([isinstance(pop, type(None)) for pop in pops]):
            raise ValueError("Condensing scheme={0} is not possible, because attribute {1}_charges "
                             "of molecule instances is 'None'.".format(scheme, scheme.lower()))
        # make dictionary of populations
        dict_pops = dict([(sum(m.mo.nelectrons), m.numbers - pop) for m, pop in zip(molecule, pops)])
        return dict_pops

    # case of condensing the density using denspart
    try:
        # check whether molecules have the same coordinates
        get_matching_attr(molecule, "coordinates", 1.e-4)
        same_coordinates = True
    except ValueError:
        if approach.lower() == "fmr":
            raise ValueError("When geometries of molecules are different, only approach='RMF' "
                             "is possible! Given approach={0}".format(approach.upper()))
        same_coordinates = False

    # find reference molecule
    if isinstance(molecule, Molecule):
        mol0 = molecule
    elif np.all([isinstance(mol, Molecule) for mol in molecule]):
        if len(molecule) != 3:
            raise ValueError("Condensing within FD approach, currently works for "
                             "only 3 molecules! Given {0} molecules.".format(len(molecule)))
        # reference molecule is the middle molecule (for 3 molecules)
        dict_mols = {sum(mol.mo.nelectrons): mol for mol in molecule}
        mol0 = dict_mols.pop(sorted(dict_mols.keys())[1])
    else:
        raise ValueError("Argument molecule not recognized!")

    # check and generate partitioning class & proatomdb
    wpart = wpart_schemes[scheme]
    # make proatom database
    if scheme.lower() not in ["mbis", "b"]:
        if "proatomdb" not in list(kwargs.keys()) or kwargs["proatomdb"] is None:
            proatomdb = ProAtomDB.from_refatoms(mol0.numbers)
            kwargs["proatomdb"] = proatomdb

    # check or generate molecular grid
    grid = get_molecular_grid(molecule, kwargs.pop("grid", None))
    # compute dictionary of number of electron and density
    dict_dens = get_dict_density(molecule, grid.points)

    # compute population of reference molecule
    part0 = wpart(mol0.coordinates, mol0.numbers, mol0.pseudo_numbers, grid,
                  dict_dens[sum(mol0.mo.nelectrons)], **kwargs)
    part0.do_all()
    # record population of reference system
    dict_pops = dict([(sum(mol0.mo.nelectrons), part0["populations"])])
    del dict_dens[sum(mol0.mo.nelectrons)]

    # compute and record populations given grid in a dictionary
    for nelec, dens in dict_dens.items():

        if approach.lower() == "fmr":
            # fragment of molecular response
            pops = condense_to_atoms(dens, part0)
        elif approach.lower() == "rmf":
            # response of molecular fragment
            if not same_coordinates:
                mol = dict_mols[nelec]
                grid = get_molecular_grid(molecule, None)
                dens = molecule.compute_density(grid.points, "ab", None)
            else:
                mol = mol0
            parts = wpart(mol.coordinates, mol.numbers, mol.pseudo_numbers,
                          grid, dens, **kwargs)

            parts.do_all()
            pops = parts["populations"]
        else:
            raise ValueError("Condensing approach {0} is not recognized!".format(approach))
        # Store number of electron and populations in a dictionary
        dict_pops[nelec] = pops
    return dict_pops
Пример #15
0
def main_convert(args):
    # The atomic grid specification
    agspec = AtomicGridSpec(args.grid)

    # The program is detected based on the run script that is present
    run_scripts = glob("run_*.sh")
    if len(run_scripts) != 1:
        raise RuntimeError('Found %i run_*.sh scripts while exactly one is needed to know which program was used to run the atomic computations.' % len(run_scripts))
    program = atom_programs[run_scripts[0][4:-3]]

    # Loop over all sensible directories
    energy_table = EnergyTable()
    records = []
    for dn_state in sorted(glob("[01]??_??_[01]??_q[+-]??")):
        number = int(dn_state[:3])
        pop = int(dn_state[7:10])

        cases = []
        for dn_mult in sorted(glob('%s/mult??' % dn_state)):
            if log.do_medium:
                log('Loading from', dn_mult)
            system, energy = program.load_atom(dn_mult)
            if energy is None:
                if log.do_medium:
                    log('No (sensible) results found:  ', dn_mult)
                continue
            cases.append((energy, system))

        if len(cases) == 0:
            if log.do_medium:
                log('Nothing found in:  ', dn_state)
            continue

        # Get the lowest in energy and write to chk file
        cases.sort()
        energy, system = cases[0]

        # Add case to energy table
        energy_table.add(number, pop, energy)

        # Write system to Horton file if possible
        if system is not None:
            system.assign_chk('%s/horton.h5' % dn_state)

        # Construct a record for the proatomdb
        records.append(ProAtomRecord.from_system(system, agspec))

        # Release memory and close h5 files
        system = None
        del cases

        # Let user know we are alive.
        if log.do_medium:
            log('Succesfull:        ', dn_state)

    # Report energies
    if log.do_medium:
        energy_table.log()

    # Write out atoms file
    proatomdb = ProAtomDB(records)
    proatomdb.to_file('atoms.h5')
    if log.do_medium:
        log('Written atoms.h5')

    # Make nice figures
    plot_atoms(proatomdb)
Пример #16
0
def get_proatomdb_hf_lan():
    '''Return a proatomdb of H, O, Si at hf/LANL2MB for testing purposes'''
    fns = glob(context.get_fn('test/atom_???_???_hf_lan.fchk'))
    return ProAtomDB.from_files(fns)
Пример #17
0
def get_proatomdb_hf_sto3g():
    '''Return a proatomdb of H and O at hf/sto-3g for testing purposes'''
    fns = glob(context.get_fn('test/atom_???_???_hf_sto3g.fchk'))
    return ProAtomDB.from_files(fns)
Пример #18
0
def get_proatomdb_cp2k():
    '''Return a proatomdb of pseudo oxygens and one silicon for testing purposes'''
    fns = glob(context.get_fn('test/atom_*.cp2k.out'))
    return ProAtomDB.from_files(fns)