def store_enumeration(self, filename=None):
        for SG in range(self.SG_start, self.SG_end + 1):
            with PrototypeSQL(filename=filename) as DB:
                enumerated = [DB.is_enumerated(self.stoichiometry,
                                               SG, num, self.num_type)
                              for num in range(self.num_start, self.num_end + 1)]
                if np.all(enumerated):
                    print('spacegroup={} already enumerated for n_{}={}:{}'
                          .format(SG, self.num_type,
                                  self.num_start, self.num_end))
                    continue
            E = be.enumerator.ENUMERATOR()
            try:
                enumerations = E.get_bulk_enumerations(
                    self.stoichiometry,
                    self.num_start,
                    self.num_end,
                    SG,
                    SG,
                    self.num_type)

                print('Found {} prototypes for spacegroup={}'.format(
                    len(enumerations), SG))
            except:
                print('Found 0 prototypes for spacegroup={}'.format(SG))

            with PrototypeSQL(filename=filename) as DB:
                for entry in enumerations:
                    entry.update({'source': 'prototype'})
                    DB.write_prototype(entry=entry)

                for num in range(self.num_start, self.num_end + 1):
                    DB.write_enumerated(self.stoichiometry, SG, num,
                                        self.num_type)
    def store_atom_enumeration(self, filename=None, multithread=False,
                               max_candidates=1):
        self.filename = filename
        DB = PrototypeSQL(filename=filename)
        DB._connect()
        N0 = DB.ase_db.count()

        prototypes = DB.select(max_atoms=self.max_atoms,
                               spacegroups=self.spacegroups,
                               source='prototype')
        Nprot = len(prototypes)

        pool = Pool()

        t0 = time.time()
        if multithread:
            res = pool.amap(self.store_atoms_for_prototype, prototypes)
            while not res.ready():
                N = DB.ase_db.count() - N0
                t = time.time() - t0
                N_per_t = N / t
                if N > 0:
                    print('---------------------------------')
                    print(
                        "{}/{} structures generated in {:.2f} sec".format(N, Nprot, t))
                    print("{} sec / structure".format(t / N))
                    print('Estimated time left: {:.2f} min'.format(
                        Nprot / N_per_t / 60))
                print('---------------------------------')
                time.sleep(10)
            res = res.get()
        else:
            for prototype in prototypes:
                self.store_atoms_for_prototype(prototype)
Exemple #3
0
    def store_enumeration(self, filename, chemical_formula, max_atoms=None):
        """ Saves the enumerated prototypes and atomic species in a database"""

        distinct_protonames = \
            self.get_distinct_prototypes(
                chemical_formula=chemical_formula,
                max_atoms=max_atoms)

        for count, proto_name in enumerate(distinct_protonames):
            data_list = \
                self.get_atoms_for_prototype(chemical_formula,
                                             proto_name)

            DB = PrototypeSQL(filename=filename)

            for d in data_list:
                atoms = d.pop('atoms')

                formula = d.pop('chemical_formula')
                original_formula = d.pop('original_formula')

                # Same format as Enumerator output
                entry = d.copy()
                entry['spaceGroupNumber'] = entry.pop('spacegroup')
                entry['name'] = entry.pop('p_name')
                entry['parameters'] = {}
                entry['source'] = 'icsd'

                structure_name = d['structure_name']

                if DB.ase_db.count(structure_name=structure_name) > 0:
                    continue

                # Save prototype
                DB.write_prototype(entry=entry)


                key_value_pairs = \
                    {'p_name': d['p_name'],
                     'spacegroup': d['spacegroup'],
                     'permutations': json.dumps(d['specie_permutations']),
                     'wyckoffs': json.dumps(d['wyckoffs']),
                     'species': json.dumps(d['species']),
                     'structure_name': structure_name,
                     'source': 'icsd',
                     'relaxed': 0,
                     'completed': 0,
                     'submitted': 0}

                # Save structure
                DB.ase_db.write(atoms, key_value_pairs)

            if (count + 1) % 10 == 0:
                print('  {}/{} completed'.format(count + 1,
                                                 len(distinct_protonames)))
    def store_atoms_for_prototype(self, prototype, max_candidates=1):

        p_name = prototype['name']
        counts = []
        for a in p_name.split('_')[0]:
            if a.isdigit():
                counts[-1] += int(a) - 1
            else:
                counts += [1]

        species_lists = self.get_species_lists(
            prototype['species'], prototype['permutations'], counts)

        cell_parameters = prototype.get('cell_parameters', None)
        if cell_parameters:
            cell_parameters = json.load(cell_parameters)
        for species in species_lists:
            structure_name = str(prototype['spacegroup'])
            for spec, wy_spec in zip(species, prototype['wyckoffs']):
                structure_name += '_{}_{}'.format(spec, wy_spec)
            with PrototypeSQL(filename=self.filename) as DB:
                if DB.ase_db.count(structure_name=structure_name) > 0:
                    continue

                for row in DB.ase_db.select(p_name=prototype['name'], limit=1):
                    cell_parameters = json.loads(row.cell_parameters)

            BB = BuildBulk(prototype['spacegroup'],
                           prototype['wyckoffs'],
                           species,
                           )
            atoms_list, parameters = \
                BB.get_wyckoff_candidate_atoms(proximity=1,
                                               primitive_cell=True,
                                               return_parameters=True,
                                               max_candidates=max_candidates)

            key_value_pairs = {'p_name': prototype['name'],
                               'spacegroup': prototype['spacegroup'],
                               'wyckoffs':
                               json.dumps(prototype['wyckoffs']),
                               'species': json.dumps(species),
                               'structure_name': structure_name,
                               'source': 'prototype',
                               'relaxed': 0,
                               'completed': 0,
                               'submitted': 0}

            for i, atoms in enumerate(atoms_list):
                atoms.info.pop('spacegroup')
                if 'spacegroup_kinds' in atoms.info:
                    atoms.info.pop('spacegroup_kinds')
                key_value_pairs.update(atoms.info)
                key_value_pairs.update(
                    {'cell_parameters': json.dumps(parameters[i])})

                fitness = get_fitness(atoms)
                apf = get_covalent_density(atoms)

                key_value_pairs.update({'fitness': fitness,
                                        'apf': apf})

                with PrototypeSQL(filename=self.filename) as DB:
                    DB.ase_db.write(atoms, key_value_pairs)