Beispiel #1
0
 def computeEnergy(self, structure, return_prj_mat=False):
     logging.info("Start energy ...")
     energy = 0.0
     spectrum = soap.Spectrum(structure, self.options, self.basis)
     spectrum.compute()
     spectrum.computePower()
     spectrum.computePowerGradients()
     # TODO The kernel policy should take care of this:
     if self.use_global_spectrum:
         spectrum.computeGlobal()
     IX_acqu = self.adaptor.adapt(spectrum)
     n_acqu = IX_acqu.shape[0]
     dim_acqu = IX_acqu.shape[1]
     logging.info("Compute energy from %d atomic environments ..." % n_acqu)
     projection_matrix = []
     for n in range(n_acqu):
         X = IX_acqu[n]
         #print "X_MAG", np.dot(X,X)
         ic = self.kernelfct.compute(self.IX, X)
         energy += self.alpha.dot(ic)
         #print "Projection", ic
         projection_matrix.append(ic)
     if return_prj_mat:
         return energy, projection_matrix
     else:
         return energy
Beispiel #2
0
 def acquire(self, structure, alpha):
     logging.info("Acquire ...")
     spectrum = soap.Spectrum(structure, self.options, self.basis)
     spectrum.compute()
     spectrum.computePower()
     spectrum.computePowerGradients()
     # New X's
     logging.info("Adapt spectrum ...")
     IX_acqu = self.adaptor.adapt(spectrum, self.pid_list_acquire)
     n_acqu = IX_acqu.shape[0]
     dim_acqu = IX_acqu.shape[1]
     # New alpha's
     alpha_acqu = np.zeros((n_acqu))
     alpha_acqu.fill(alpha)
     if not self.dimX:
         # First time ...
         self.dimX = dim_acqu
         self.IX = IX_acqu
         self.alpha = alpha_acqu
     else:
         # Check and extend ...
         assert self.dimX == dim_acqu  # Acquired descr. should match linear dim. of previous descr.'s
         I = self.IX.shape[0]
         self.IX.resize((I + n_acqu, self.dimX))
         self.IX[I:I + n_acqu, :] = IX_acqu
         self.alpha.resize((I + n_acqu))
         self.alpha[I:I + n_acqu] = alpha_acqu
     #print self.alpha
     #print self.IX
     logging.info("Acquired %d environments." % n_acqu)
     return
Beispiel #3
0
def compute_soap(struct, options):
    # OPTIONS
    options_soap = soap.Options()
    for key, val in options.items():
        if isinstance(val, list):
            continue
        options_soap.set(key, val)
    # Exclusions
    excl_targ_list = options['exclude_targets']
    excl_cent_list = options['exclude_centers']
    options_soap.excludeCenters(excl_cent_list)
    options_soap.excludeTargets(excl_targ_list)
    # Compute spectrum
    spectrum = soap.Spectrum(struct, options_soap)
    spectrum.compute()
    spectrum.computePower()
    if options['spectrum.gradients']:
        spectrum.computePowerGradients()
    if options['spectrum.global']:
        spectrum.computeGlobal()
    # Adapt spectrum
    adaptor = soap.soapy.kernel.KernelAdaptorFactory[options['kernel.adaptor']](
        options_soap,
        types_global=options['type_list'])
    IX, IR, types = adaptor.adapt(spectrum, return_pos_matrix=True)
    # Calculate average
    X_avg = IX.sum(axis=0)
    X_avg = X_avg / X_avg.dot(X_avg)**0.5
    return IX, X_avg, IR, types
Beispiel #4
0
def compute_spectrum(config, options_dict, exclude_centers, exclude_targets):
    # ANNOUNCE
    global MP_LOCK
    MP_LOCK.acquire()
    osio << osio.item \
         << "Soap for:  " << config.config_file \
         << "PID=%d" % mp.current_process().pid << endl
    MP_LOCK.release()
    # SET OPTIONS
    options = soap.Options()
    for item in options_dict.iteritems():
        options.set(*item)
    options.excludeCenters(exclude_centers)
    options.excludeTargets(exclude_targets)
    # PROCESS STRUCTURE
    structure = soap.tools.setup_structure_ase(config.config_file,
                                               config.atoms)
    for particle in structure:
        particle.sigma = 0.5 * element_vdw_radius[particle.type]
        particle.weight = element_valence_order[particle.type]
    # COMPUTE SPECTRUM
    spectrum = soap.Spectrum(structure, options)
    spectrum.compute()
    spectrum.computePower()
    spectrum.save('%s.spectrum' % config.config_file)
    return config.config_file
Beispiel #5
0
    def load(self, hdf5_handle):
        g = hdf5_handle
        # SETTINGS
        self.settings = g.attrs
        self.label = g["class"].attrs["label"]
        if self.verbose:
            self.log << self.log.mb << "Loading power spectrum '%s'" % self.label << self.log.endl

        # HELPER FUNCTIONS
        def load_dict_array_data(h):
            D = []
            for idx in range(len(h)):
                hh = h["%d" % idx]
                d = {t: hh[t].value for t in hh}
                D.append(d)
            return D

        def load_descriptor_map_matrix(h):
            D = soap.soapy.kernel.DescriptorMapMatrix()
            for idx in range(len(h)):
                d = soap.soapy.kernel.DescriptorMap()
                hh = h['%d' % idx]
                for t in hh:
                    d[t] = hh[t].value
                D.append(d)
            return D

        # LOAD FIELDS
        if self.settings["store_cxx_serial"]:
            if self.verbose:
                self.log << "[h5] Loading cxx serial and spectrum" << self.log.endl
            cxx_serial = g["cxx_serial"].value.tostring()
            self.spectrum = soap.Spectrum()
            self.spectrum.loads(cxx_serial)
            self.has_spectrum = True
        # DENSITY EXPANSION COEFFICIENTS
        if self.settings["store_cmap"]:
            if self.verbose:
                self.log << "[h5] Loading coefficient map" << self.log.endl
            self.cmap = load_dict_array_data(g["cmap"])
        if self.settings["store_gcmap"]:
            if self.verbose:
                self.log << "[h5] Loading global coefficient map" << self.log.endl
            self.cmap = load_dict_array_data(g["gcmap"])
        # POWER SPECTRUM COEFFICIENTS
        if self.settings["store_sdmap"]:
            if self.verbose:
                self.log << "[h5] Loading descriptor map" << self.log.endl
            self.sdmap = load_descriptor_map_matrix(g["sdmap"])
        if self.settings["store_gsdmap"]:
            if self.verbose:
                self.log << "[h5] Loading global descriptor map" << self.log.endl
            self.gsdmap = load_descriptor_map_matrix(g["gsdmap"])
        if self.settings["store_sd"]:
            if self.verbose:
                self.log << "[h5] Loading descriptor matrix" << self.log.endl
            self.sd = g["sd"].value
        return self
Beispiel #6
0
 def compute(self, config, options, config_target=None, converter=None):
     if self.has_cnlm: pass
     else:
         # CONVERT ASE ATOMS TO SOAPXX TOPOLOGY
         if converter is None: converter = PowerSpectrum.converter
         self.structure = converter.convert(self.config)
         if config_target is not None:
             self.structure_target = converter.convert(self.config_target)
         self.has_structure = True
         # COMPUTE SPECTRUM
         options_cxx = convert_json_to_cxx(options)
         self.spectrum = soap.Spectrum(self.structure, options_cxx)
         if self.verbose:
             self.log << "[cc] Computing density expansion" << self.log.endl
         if self.structure_target is not None:
             self.spectrum.compute(self.structure, self.structure_target)
         else:
             self.spectrum.compute()
         self.has_spectrum = True
         # EXTRACT CNLM ATOMIC
         if PowerSpectrum.settings["store_cmap"]:
             if self.verbose:
                 self.log << "[py] Storing coefficient map (-> cmap)" << self.log.endl
             self.cmap = []
             for atomic in self.spectrum:
                 cmap = {}
                 types = atomic.getTypes()
                 for t in types:
                     cnlm = atomic.getLinear(t).array
                     cmap[t] = cnlm
                 self.cmap.append(cmap)
         # EXTRACT CNLM GLOBAL
         if PowerSpectrum.settings["store_gcmap"]:
             if self.verbose:
                 self.log << "[cc] Computing global coefficient map" << self.log.endl
             self.gcmap = []
             self.spectrum_global = self.spectrum.computeGlobal()
             if self.verbose:
                 self.log << "[py] Storing global coefficient map (-> gcmap)" << self.log.endl
             types = atomic.getTypes()
             for t in types:
                 self.gcmap.append({t: atomic.getLinear(t).array})
             self.has_spectrum_global = True
         self.has_cnlm = True
         # COMPUTE POWER SPECTRUM?
         if PowerSpectrum.settings["cxx_compute_power"]:
             self.computePower()
     return
Beispiel #7
0
    def computeForces(self, structure, verbose=False):
        logging.info("Start forces ...")
        if verbose:
            for p in structure:
                print p.pos
        forces = [np.zeros((3)) for i in range(structure.n_particles)]
        logging.info("Compute forces on %d particles ..." %
                     structure.n_particles)
        # Compute X's, dX's
        spectrum = soap.Spectrum(structure, self.options, self.basis)
        spectrum.compute()
        spectrum.computePower()
        spectrum.computePowerGradients()
        if self.use_global_spectrum:
            atomic_global = spectrum.computeGlobal()
            spectrum_iter = [atomic_global]
        else:
            spectrum_iter = spectrum
        # Extract & compute force
        for atomic in spectrum_iter:
            pid = atomic.getCenter().id if not self.use_global_spectrum else -1
            #if not pid in self.pid_list_force:
            #    logging.debug("Skip forces derived from environment with pid = %d" % pid)
            #    continue
            #if pid != 1: continue
            nb_pids = atomic.getNeighbourPids()
            logging.info("  Center %d" % (pid))
            # neighbour-pid-independent kernel "prevector" (outer derivative)
            X_unnorm, X_norm = self.adaptor.adaptScalar(atomic)
            dIC = self.kernelfct.computeDerivativeOuter(self.IX, X_norm)
            alpha_dIC = self.alpha.dot(dIC)
            for nb_pid in nb_pids:
                # Force on neighbour
                logging.info("    -> Nb %d" % (nb_pid))
                dX_dx, dX_dy, dX_dz = self.adaptor.adaptGradients(
                    atomic, nb_pid, X_unnorm)

                force_x = -alpha_dIC.dot(dX_dx)
                force_y = -alpha_dIC.dot(dX_dy)
                force_z = -alpha_dIC.dot(dX_dz)

                forces[nb_pid - 1][0] += force_x
                forces[nb_pid - 1][1] += force_y
                forces[nb_pid - 1][2] += force_z
                #print forces
                #raw_input('...')
        return forces
Beispiel #8
0
 def compute(self, config, options):
     if self.has_cnlm: pass
     else:
         # CONVERT ASE ATOMS TO SOAPXX TOPOLOGY
         self.config, self.structure, top, frag_bond_mat, atom_bond_mat, frag_labels, atom_labels = \
             soap.tools.structure_from_ase(
                 config,
                 do_partition=False,
                 add_fragment_com=False,
                 log=None)
         self.has_structure = True
         # COMPUTE SPECTRUM
         options_cxx = self.getCxxOptions(options)
         self.spectrum = soap.Spectrum(self.structure, options_cxx)
         if self.verbose:
             self.log << "[cc] Computing density expansion" << self.log.endl
         self.spectrum.compute()
         self.has_spectrum = True
         # EXTRACT CNLM ATOMIC
         if PowerSpectrum.settings["store_cmap"]:
             if self.verbose:
                 self.log << "[py] Storing coefficient map (-> cmap)" << self.log.endl
             self.cmap = []
             for atomic in self.spectrum:
                 cmap = {}
                 types = atomic.getTypes()
                 for t in types:
                     cnlm = atomic.getLinear(t).array
                     cmap[t] = cnlm
                 self.cmap.append(cmap)
         # EXTRACT CNLM GLOBAL
         if PowerSpectrum.settings["store_gcmap"]:
             if self.verbose:
                 self.log << "[cc] Computing global coefficient map" << self.log.endl
             self.gcmap = []
             self.spectrum_global = self.spectrum.computeGlobal()
             if self.verbose:
                 self.log << "[py] Storing global coefficient map (-> gcmap)" << self.log.endl
             types = atomic.getTypes()
             for t in types:
                 self.gcmap.append({t: atomic.getLinear(t).array})
             self.has_spectrum_global = True
         self.has_cnlm = True
         # COMPUTE POWER SPECTRUM?
         if PowerSpectrum.settings["cxx_compute_power"]:
             self.computePower()
     return
Beispiel #9
0
 def computeEnergy(self, structure):
     logging.info("Start energy ...")
     energy = 0.0
     spectrum = soap.Spectrum(structure, self.options, self.basis)
     spectrum.compute()
     spectrum.computePower()
     spectrum.computePowerGradients()
     IX_acqu = self.adaptor.adapt(spectrum, self.pid_list_acquire)
     n_acqu = IX_acqu.shape[0]
     dim_acqu = IX_acqu.shape[1]
     logging.info("Compute energy from %d atomic environments ..." % n_acqu)
     for n in range(n_acqu):
         X = IX_acqu[n]
         ic = self.kernelfct.compute(self.IX, X)
         energy += self.alpha.dot(ic)
         print "Projection", ic
     return energy
Beispiel #10
0
def compute_soap(struct, options, fragment_based=False):
    # OPTIONS
    options_soap = soap.Options()
    for key, val in options.items():
        if type(val) == list: continue
        options_soap.set(key, val)
    # Exclusions
    excl_targ_list = options['exclude_targets']
    excl_cent_list = options['exclude_centers']
    excl_targ_list.append('COM')
    if not fragment_based:
        excl_cent_list.append('COM')
    options_soap.excludeCenters(excl_cent_list)
    options_soap.excludeTargets(excl_targ_list)
    # SPECTRUM
    spectrum = soap.Spectrum(struct, options_soap)
    # Compute density expansion
    if fragment_based:
        # Divide onto segments and their COM representatives
        seg_by_name = {}
        comseg_by_name = {}
        for seg in struct.segments:
            if seg.name.split('.')[-1] == 'COM':
                comseg_by_name[seg.name] = seg
            else:
                seg_by_name[seg.name] = seg
        # Compute segment descriptors
        for name, seg in seg_by_name.items():
            comseg = comseg_by_name[name + '.COM']
            spectrum.compute(comseg, seg)
    else:
        spectrum.compute()
    # Compute power spectrum,
    spectrum.computePower()
    if options['spectrum.gradients']:
        spectrum.computePowerGradients()
    if options['spectrum.global']:
        spectrum.computeGlobal()
    # Adapt spectrum
    adaptor = soap.soapy.kernel.KernelAdaptorFactory[
        options['kernel.adaptor']](options_soap,
                                   types_global=options['type_list'])
    IX, IR, types = adaptor.adapt(spectrum, return_pos_matrix=True)
    return IX, IR, types
Beispiel #11
0
 def acquire(self, reset=True):
     if reset: self.reset()
     # Compute spectrum
     self.spectrum = soap.Spectrum(self.structure, self.options, self.basis)
     self.spectrum.compute()
     self.spectrum.computePower()
     self.spectrum.computePowerGradients()
     self.spectrum.computeGlobal()
     # PID-resolved storage for X, dX
     for atomic in self.adaptor.getListAtomic(self.spectrum):
         pid = atomic.getCenterId()
         X_unnorm, X_norm = self.adaptor.adaptScalar(
             atomic)  # TODO Done again below in ::adapt => simplify
         self.pid_X_unnorm[pid] = X_unnorm
         self.pid_X_norm[pid] = X_norm
         self.pid_nbpid_dX[pid] = {}
         # NB-PID-resolved derivatives
         nb_pids = atomic.getNeighbourPids()
         for nb_pid in nb_pids:
             dX_dx, dX_dy, dX_dz = self.adaptor.adaptGradients(
                 atomic, nb_pid, X_unnorm)
             self.pid_nbpid_dX[pid][nb_pid] = (dX_dx, dX_dy, dX_dz)
     # New X's
     IX_acqu = self.adaptor.adapt(self.spectrum)
     n_acqu = IX_acqu.shape[0]
     dim_acqu = IX_acqu.shape[1]
     if not self.dimX:
         # First time ...
         self.dimX = dim_acqu
         self.IX = IX_acqu
     else:
         # Check and extend ...
         assert self.dimX == dim_acqu  # Acquired descr. should match linear dim. of previous descr.'s
         I = self.IX.shape[0]
         self.IX.resize((I + n_acqu, self.dimX))
         self.IX[I:I + n_acqu, :] = IX_acqu
     return
Beispiel #12
0
#! /usr/bin/env python
import soap
import soap.tools

import os
import numpy as np
from momo import osio, endl, flush

archfile = 'config_000057.xyz.spectrum.arch'

# SPECTRUM
spectrum = soap.Spectrum(archfile)
structure = spectrum.structure
basis = spectrum.basis
options = spectrum.options
osio << osio.mb << options << endl

center_id = 1
center_type = "C"
density_type = "O"

# TARGET EXTRACTION
atomic = spectrum.getAtomic(center_id, center_type)
center = atomic.getCenter()
atomic_xnkl = atomic.getPower(density_type, density_type).array

# INVERT XKNL => QNLM
atomic_inv_qnlm = soap.tools.invert_xnkl_aa(atomic_xnkl, basis, l_smaller=0, l_larger=1)

# CREATE INVERSION EXPANSION
basisexp = soap.BasisExpansion(basis)
Beispiel #13
0
 target = target_map[id1][id2]
 # READ COORDINATES
 ase_config_list = soap.tools.ase_load_all('dim')
 assert len(ase_config_list) == 1
 config = ase_config_list[0]
 # PROCESS STRUCTURE
 structure = soap.tools.setup_structure_ase(config.config_file,
                                            config.atoms)
 for particle in structure:
     particle.sigma = 0.5 * element_vdw_radius[particle.type]
     particle.weight = element_valence_order[particle.type]
     if particle.id > 28:
         #print particle.id, particle.name
         particle.weight *= -1.
 # COMPUTE SPECTRUM
 spectrum = soap.Spectrum(structure, options)
 basis = spectrum.basis
 spectrum.compute()
 spectrum.computePower()
 # EXTRACT XNKL
 x_pair = soap.PowerExpansion(spectrum.basis)
 xnkl_pair = x_pair.array
 norm = 0.
 for atomic in spectrum:
     xnkl_pair = xnkl_pair + atomic.getPower("", "").array
     norm += 1.
 xnkl_pair = xnkl_pair / norm
 xnkl_pair = xnkl_pair.real
 xnkl_pair = xnkl_pair.reshape(basis.N * basis.N * (basis.L + 1))
 # SAVE TO HARDDRIVE
 np.save('xnkl.array.npy', xnkl_pair)
Beispiel #14
0
 def setupVertexFeatures(self, atoms, options):
     n_atoms = len(atoms)
     positions = [atom.position for atom in atoms]
     descriptor_type = options['graph']['descriptor']
     options_descriptor = options['descriptor'][descriptor_type]
     if descriptor_type == 'atom_type':
         feature_map = {}
         feature_list = options_descriptor['type_map']
         dim = len(feature_list)
         P = np.zeros((n_atoms, dim))
         for idx, atom in enumerate(atoms):
             p = np.zeros((dim))
             atom_type = atom.number
             for i in range(dim):
                 if feature_list[i] == atom_type: p[i] = 1
                 else: p[i] = 0
             P[idx, :] = p
     elif descriptor_type == 'soap':
         # Structure
         structure = soap.tools.setup_structure_ase(self.label, atoms)
         # Customize density
         density_type = options["atomic_density"]["density_type"]
         use_covrad = options["atomic_density"]["use_covrad"]
         atom_rad_scale = float(options["atomic_density"]["atomic_radius"])
         # ... Particle radii
         if use_covrad:
             radius_map = soap.soapy.elements.periodic_table.getPropertyDict(
                 "covrad", convert=lambda x: x * atom_rad_scale)
         else:
             radius_map = {}
             for elem in soap.soapy.elements.PeriodicTable.element_names:
                 radius_map[elem] = atom_rad_scale
         # ... Particle 'charge'
         if density_type == "elneg_density":
             charge_map = soap.soapy.elements.periodic_table.getPropertyDict(
                 "elneg")
         elif density_type == "z_density":
             charge_map = soap.soapy.elements.periodic_table.getPropertyDict(
                 "z")
         elif density_type == "number_density":
             charge_map = {}
             for elem in soap.soapy.elements.PeriodicTable.element_names:
                 charge_map[elem] = 1.
         elif density_type == "number_density_generic":
             charge_map = {}
             for elem in soap.soapy.elements.PeriodicTable.element_names:
                 charge_map[elem] = 1.
         elif density_type == "valence_charge_density":
             charge_map = soap.soapy.elements.periodic_table.getPropertyDict(
                 "valence")
         else:
             raise NotImplementedError("Density type '%s'" % density_type)
         # ... Apply
         soap.tools.setup_structure_density(structure,
                                            radius_map=radius_map,
                                            charge_map=charge_map)
         # Options
         options_soap = soap.Options()
         for item in options_descriptor.items():
             key = item[0]
             val = item[1]
             if type(val) == list:
                 continue  # TODO Exclusions loaded separately, fix this
             options_soap.set(key, val)
         options_soap.excludeCenters(options_descriptor['exclude_centers'])
         options_soap.excludeTargets(options_descriptor['exclude_targets'])
         # Spectrum
         spectrum = soap.Spectrum(structure, options_soap)
         spectrum.compute()
         spectrum.computePower()
         if options_descriptor['spectrum.gradients']:
             spectrum.computePowerGradients()
         spectrum.computeGlobal()
         # Adapt spectrum
         adaptor = kern.KernelAdaptorFactory[options_soap.get(
             'kernel.adaptor')](
                 options_soap, types_global=options_descriptor['type_list'])
         ix = adaptor.adapt(spectrum)
         dim = ix.shape[1]
         P = ix
         if options_soap.get('kernel.adaptor') in [
                 'global-generic', 'global-specific'
         ]:
             pass
         else:
             assert P.shape[0] == n_atoms
     elif descriptor_type == 'soap-quippy':
         atoms_quippy = datasets.gdb.convert_ase2quippy_atomslist([atoms
                                                                   ])[0]
         # Read options
         options_xml_file = options_descriptor["options_xml"]
         opt_interface = momo.OptionsInterface()
         xml_options = opt_interface.ParseOptionsFile(
             options_xml_file, 'options')
         # Finalize options
         xml_options.kernel.alchemy = xml_options.kernel.alchemy.As(str)
         xml_options.kernel.alchemy_rules = xml_options.kernel.alchemy
         xml_options.soap.nocenter = xml_options.soap.nocenter.As(str)
         xml_options.soap.noatom = []  # TODO
         if xml_options.soap.nocenter and xml_options.soap.nocenter != 'None':
             xml_options.soap.nocenter = map(
                 int, xml_options.soap.nocenter.split())
         else:
             xml_options.soap.nocenter = []
         datasets.soap.finalize_options([], xml_options)
         # Process
         z_types = options_descriptor["z_type_list"]
         struct = libmatch.structures.structure(xml_options.kernel.alchemy)
         soap_raw = struct.parse(atoms_quippy,
                                 xml_options.soap.R.As(float),
                                 xml_options.soap.N.As(int),
                                 xml_options.soap.L.As(int),
                                 xml_options.soap.sigma.As(float),
                                 xml_options.soap.w0.As(float),
                                 xml_options.soap.nocenter,
                                 xml_options.soap.noatom,
                                 types=z_types,
                                 kit=xml_options.kernel.kit)
         # Assign raw soaps to atoms (currently stored by z-key)
         z_idx_counter = {}
         for z in soap_raw:
             #print z, soap_raw[z].shape
             z_idx_counter[z] = 0
         ix = []
         for i, z in enumerate(atoms.get_atomic_numbers()):
             z_idx = z_idx_counter[z]
             ix.append(soap_raw[z][z_idx])
             z_idx_counter[z] += 1
             #print z, z_idx
         P = np.array(ix)
         dim = P.shape[1]
         assert P.shape[0] == n_atoms
         #print P.dot(P.T)
     elif descriptor_type == 'npy_load':
         folder = options_descriptor["folder"]
         npy_file = '%s/%s.x.npy' % (folder, self.label)
         #print npy_file
         P = np.load(npy_file)
         dim = P.shape[1]
         assert P.shape[0] == n_atoms
     elif descriptor_type == 'none':
         dim = 1
         P = np.zeros((n_atoms, dim))
         for idx, atom in enumerate(atoms):
             P[idx, 0] = 1.
     else:
         raise NotImplementedError(descriptor_type)
     return P, positions