def add_snl(self, snl, force_new=False, snlgroup_guess=None): try: self.lock_db() snl_id = self._get_next_snl_id() spstruc = snl.structure.copy() spstruc.remove_oxidation_states() sf = SpacegroupAnalyzer(spstruc, SPACEGROUP_TOLERANCE) sf.get_spacegroup() sgnum = sf.get_spacegroup_number() if sf.get_spacegroup_number() \ else -1 sgsym = sf.get_spacegroup_symbol() if sf.get_spacegroup_symbol() \ else 'unknown' sghall = sf.get_hall() if sf.get_hall() else 'unknown' sgxtal = sf.get_crystal_system() if sf.get_crystal_system() \ else 'unknown' sglatt = sf.get_lattice_type() if sf.get_lattice_type( ) else 'unknown' sgpoint = sf.get_point_group() mpsnl = MPStructureNL.from_snl(snl, snl_id, sgnum, sgsym, sghall, sgxtal, sglatt, sgpoint) snlgroup, add_new, spec_group = self.add_mpsnl( mpsnl, force_new, snlgroup_guess) self.release_lock() return mpsnl, snlgroup.snlgroup_id, spec_group except: self.release_lock() traceback.print_exc() raise ValueError("Error while adding SNL!")
def add_snl(self, snl, force_new=False, snlgroup_guess=None): try: self.lock_db() snl_id = self._get_next_snl_id() spstruc = snl.structure.copy() spstruc.remove_oxidation_states() sf = SpacegroupAnalyzer(spstruc, SPACEGROUP_TOLERANCE, ANGLE_TOLERANCE) sf.get_spacegroup() sgnum = sf.get_spacegroup_number() if sf.get_spacegroup_number() \ else -1 sgsym = sf.get_spacegroup_symbol() if sf.get_spacegroup_symbol() \ else 'unknown' sghall = sf.get_hall() if sf.get_hall() else 'unknown' sgxtal = sf.get_crystal_system() if sf.get_crystal_system() \ else 'unknown' sglatt = sf.get_lattice_type() if sf.get_lattice_type() else 'unknown' sgpoint = sf.get_point_group() mpsnl = MPStructureNL.from_snl(snl, snl_id, sgnum, sgsym, sghall, sgxtal, sglatt, sgpoint) snlgroup, add_new, spec_group = self.add_mpsnl(mpsnl, force_new, snlgroup_guess) self.release_lock() return mpsnl, snlgroup.snlgroup_id, spec_group except: self.release_lock() traceback.print_exc() raise ValueError("Error while adding SNL!")
def test_tricky_structure(self): # for some reason this structure kills spglib1.9 # 1.7 can't find symmetry either, but at least doesn't kill python s = Structure.from_file(os.path.join(test_dir, 'POSCAR.tricky_symmetry')) sa = SpacegroupAnalyzer(s, 0.1) sa.get_spacegroup_symbol() sa.get_spacegroup_number() sa.get_point_group() sa.get_crystal_system() sa.get_hall()
def test_tricky_structure(self): # for some reason this structure kills spglib1.9 # 1.7 can't find symmetry either, but at least doesn't kill python s = Structure.from_file(os.path.join(test_dir, 'POSCAR.tricky_symmetry')) sa = SpacegroupAnalyzer(s, 0.1) sa.get_spacegroup_symbol() sa.get_spacegroup_number() sa.get_point_group() sa.get_crystal_system() sa.get_hall()
def print_spg(src="POSCAR"): srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure, symprec=5e-2, angle_tolerance=8) spg = finder.get_spacegroup_symbol() spg_num = finder.get_spacegroup_number() print(spg) print(spg_num)
def create_structure_db_info(structure, spacegroup=None): # Figure out the symmetry group if not spacegroup: spacegroup = SpacegroupAnalyzer(structure, normalised_symmetry_precision(structure), -1) d = dict() # Set the composition and formulas for the system comp = structure.composition el_amt = structure.composition.get_el_amt_dict() d.update({"unit_cell_formula": comp.to_dict, "reduced_cell_formula": comp.to_reduced_dict, "elements": list(el_amt.keys()), "nelements": len(el_amt), "pretty_formula": comp.reduced_formula, "anonymous_formula": comp.anonymized_formula, "nsites": comp.num_atoms, "chemsys": "-".join(sorted(el_amt.keys()))}) d["spacegroup"] = {"symbol": unicode(spacegroup.get_spacegroup_symbol(), errors="ignore"), "number": spacegroup.get_spacegroup_number(), "point_group": unicode(spacegroup.get_point_group(), errors="ignore"), "source": "spglib", "crystal_system": spacegroup.get_crystal_system(), "hall": spacegroup.get_hall()} return d
def cif2geom_sym2(cif): parser=CifParser.from_string(cif) struct=parser.get_structures()[0] sg = SpacegroupAnalyzer(struct) struct = sg.get_conventional_standard_structure() sg = SpacegroupAnalyzer(struct) geomlines=["CRYSTAL"] geomlines += ["0 0 1"] geomlines += [str(sg.get_spacegroup_number())] cry_sys = sg.get_crystal_system() lattice = struct.lattice if cry_sys == 'trigonal' or cry_sys == 'hexagonal' or cry_sys == 'tetragonal': geomlines += ["%s %s" %(lattice.a,lattice.c)] elif cry_sys == 'cubic': geomlines += ["%s" %(lattice.a)] elif cry_sys == 'triclinic': geomlines += ["%s %s %s %s %s %s" %(lattice.a,lattice.b,lattice.c,lattice.alpha,lattice.beta,lattice.gamma)] elif cry_sys == 'monoclinic': geomlines += ["%s %s %s %s" %(lattice.a,lattice.b,lattice.c,lattice.beta)] elif cry_sys == 'orthorhombic': geomlines += ["%s %s %s" %(lattice.a,lattice.b,lattice.c)] else: print('Error printing symmetrized structure.') quit() ds = sg.get_symmetry_dataset() eq_sites = np.unique(ds['equivalent_atoms']) geomlines += [str(len(eq_sites))] for eq_site in eq_sites: site = struct.sites[eq_site] geomlines += ["%s %s %s %s" %(site.specie.Z+200,site.a,site.b,site.c)] return geomlines,struct
def process_item(self, item, index): nrow, ncol, snlgroups = super(SNLSpaceGroupChecker, self).process_item(item, index) local_mismatch_dict = dict((k,[]) for k in categories[self.checker_name]) category = '' try: mpsnl_dict = self._snls.collection.find_one({ 'snl_id': item }) mpsnl = MPStructureNL.from_dict(mpsnl_dict) mpsnl.structure.remove_oxidation_states() sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1) if sf.get_spacegroup_number() != mpsnl.sg_num: category = categories[self.checker_name][int(sf.get_spacegroup_number() == 0)] except: exc_type, exc_value, exc_traceback = sys.exc_info() category = categories[0][2] if category: local_mismatch_dict[category].append(str(item)) _log.info('(%d) %r', self._counter_total.value, local_mismatch_dict) self._increase_counter(nrow, ncol, local_mismatch_dict)
def check_snl_spacegroups(args): """check spacegroups of all available SNLs""" range_index = args.start / num_ids_per_stream idxs = [range_index * 2] idxs += [idxs[0] + 1] s = [py.Stream(stream_ids[i]) for i in idxs] for i in range(len(idxs)): s[i].open() end = num_snls if args.end > num_snls else args.end id_range = {"$gt": args.start, "$lte": end} mpsnl_cursor = sma.snl.find({"snl_id": id_range}) num_good_ids = 0 colors = [] for mpsnl_dict in mpsnl_cursor: start_time = time.clock() exc_raised = False try: mpsnl = MPStructureNL.from_dict(mpsnl_dict) sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1) except: exc_type, exc_value, exc_traceback = sys.exc_info() exc_raised = True is_good = (not exc_raised and sf.get_spacegroup_number() == mpsnl.sg_num) if is_good: # Bar (good) num_good_ids += 1 data = dict(x=[num_good_ids], y=[range_index]) else: # Scatter (bad) if exc_raised: category = 2 if fnmatch(str(exc_type), '*pybtex*') else 3 text = ' '.join([str(exc_type), str(exc_value)]) else: category = int(sf.get_spacegroup_number() == 0) text = '%s: %d' % (mpsnl.snlgroup_key, sf.get_spacegroup_number()) colors.append(category_colors[category]) data = dict(x=mpsnl_dict['snl_id'] % num_ids_per_stream, y=range_index, text=text, marker=Marker(color=colors)) s[is_good].write(data) for i in range(len(idxs)): s[i].close()
def print_spg(src='POSCAR'): """ space group を return """ srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure, symprec=5e-2, angle_tolerance=8) spg = finder.get_spacegroup_symbol() spg_num = finder.get_spacegroup_number() return spg, spg_num
def check_snl_spacegroups(args): """check spacegroups of all available SNLs""" range_index = args.start / num_ids_per_stream idxs = [range_index*2] idxs += [idxs[0]+1] s = [py.Stream(stream_ids[i]) for i in idxs] for i in range(len(idxs)): s[i].open() end = num_snls if args.end > num_snls else args.end id_range = {"$gt": args.start, "$lte": end} mpsnl_cursor = sma.snl.find({ "snl_id": id_range}) num_good_ids = 0 colors=[] for mpsnl_dict in mpsnl_cursor: start_time = time.clock() exc_raised = False try: mpsnl = MPStructureNL.from_dict(mpsnl_dict) sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1) except: exc_type, exc_value, exc_traceback = sys.exc_info() exc_raised = True is_good = (not exc_raised and sf.get_spacegroup_number() == mpsnl.sg_num) if is_good: # Bar (good) num_good_ids += 1 data = dict(x=[num_good_ids], y=[range_index]) else: # Scatter (bad) if exc_raised: category = 2 if fnmatch(str(exc_type), '*pybtex*') else 3 text = ' '.join([str(exc_type), str(exc_value)]) else: category = int(sf.get_spacegroup_number() == 0) text = '%s: %d' % (mpsnl.snlgroup_key, sf.get_spacegroup_number()) colors.append(category_colors[category]) data = dict( x=mpsnl_dict['snl_id']%num_ids_per_stream, y=range_index, text=text, marker=Marker(color=colors) ) s[is_good].write(data) for i in range(len(idxs)): s[i].close()
def run_task(self, fw_spec): btrap_dir = os.path.join(os.getcwd(), "boltztrap") bta = BoltztrapAnalyzer.from_files(btrap_dir) d = bta.as_dict() d["boltztrap_dir"] = btrap_dir # trim the output for x in ['cond', 'seebeck', 'kappa', 'hall', 'mu_steps', 'mu_doping', 'carrier_conc']: del d[x] if not self.get("hall_doping"): del d["hall_doping"] # add the structure bandstructure_dir = os.getcwd() v, o = get_vasprun_outcar(bandstructure_dir, parse_eigen=False, parse_dos=False) structure = v.final_structure d["structure"] = structure.as_dict() d.update(get_meta_from_structure(structure)) d["bandstructure_dir"] = bandstructure_dir # add the spacegroup sg = SpacegroupAnalyzer(Structure.from_dict(d["structure"]), 0.1) d["spacegroup"] = {"symbol": sg.get_spacegroup_symbol(), "number": sg.get_spacegroup_number(), "point_group": sg.get_point_group(), "source": "spglib", "crystal_system": sg.get_crystal_system(), "hall": sg.get_hall()} d["created_at"] = datetime.utcnow() db_file = env_chk(self.get('db_file'), fw_spec) if not db_file: with open(os.path.join(btrap_dir, "boltztrap.json"), "w") as f: f.write(json.dumps(d, default=DATETIME_HANDLER)) else: mmdb = MMDb.from_db_file(db_file, admin=True) # dos gets inserted into GridFS dos = json.dumps(d["dos"], cls=MontyEncoder) fsid, compression = mmdb.insert_gridfs( dos, collection="dos_boltztrap_fs", compress=True) d["dos_boltztrap_fs_id"] = fsid del d["dos"] mmdb.db.boltztrap.insert(d)
def _get_data_from_single_dirc(dirc, src_str="str_relax.out", src_ene='energy'): """ 指定したdircから構造とエネルギーを読み取る """ src = os.path.join(dirc, src_str) strout = StrOut.from_file(src) src = os.path.join(dirc, src_ene) with open(src, 'r') as rfile: lines = rfile.readlines() num_atoms = sum(strout.structure.composition. to_data_dict['unit_cell_composition'].values()) energy = float(lines[0]) / num_atoms analyzer = SpacegroupAnalyzer(strout.structure) #std_prim = analyzer.get_primitive_standard_structure() std_str = analyzer.get_conventional_standard_structure() analyzer = SpacegroupAnalyzer(std_str) wyckoffs = analyzer.get_symmetry_dataset()['wyckoffs'] formula = std_str.composition.to_data_dict['unit_cell_composition'] symbol_spg = analyzer.get_spacegroup_symbol() num_spg = analyzer.get_spacegroup_number() spg = [symbol_spg, num_spg] lattice = std_str.as_dict()['lattice'] equiv_sites = analyzer.get_symmetrized_structure().equivalent_sites equiv_indices = analyzer.get_symmetrized_structure().equivalent_indices # Wycoffs labelと組み合わせたsites_groupのlistを作る sites_and_wyckoffs = [] for eq_s, eq_i in zip(equiv_sites, equiv_indices): sites_and_wyckoffs.append({'wyckoffs': wyckoffs[eq_i[0]], 'site_grp': eq_s}) # check for i in range(len(eq_i)-1): if wyckoffs[eq_i[i]] != wyckoffs[eq_i[i+1]] or \ len(eq_s) != len(eq_i): print("wyckoffs label is wrong !!!!") print(wyckoffs) print(eq_i) print(len(eq_s)) print(dirc) exit() return {'formula': formula, 'lattice': lattice, 'spg': spg, 'sites_and_wyckoffs': sites_and_wyckoffs, 'energy': energy, 'str_id': os.path.basename(dirc)}
def cif2geom_sym2(cif): parser = CifParser.from_string(cif) struct = parser.get_structures()[0] sg = SpacegroupAnalyzer(struct) struct = sg.get_conventional_standard_structure() sg = SpacegroupAnalyzer(struct) geomlines = ["CRYSTAL"] geomlines += ["0 0 1"] geomlines += [str(sg.get_spacegroup_number())] cry_sys = sg.get_crystal_system() lattice = struct.lattice if cry_sys == 'trigonal' or cry_sys == 'hexagonal' or cry_sys == 'tetragonal': geomlines += ["%s %s" % (lattice.a, lattice.c)] elif cry_sys == 'cubic': geomlines += ["%s" % (lattice.a)] elif cry_sys == 'triclinic': geomlines += [ "%s %s %s %s %s %s" % (lattice.a, lattice.b, lattice.c, lattice.alpha, lattice.beta, lattice.gamma) ] elif cry_sys == 'monoclinic': geomlines += [ "%s %s %s %s" % (lattice.a, lattice.b, lattice.c, lattice.beta) ] elif cry_sys == 'orthorhombic': geomlines += ["%s %s %s" % (lattice.a, lattice.b, lattice.c)] else: print('Error printing symmetrized structure.') quit() ds = sg.get_symmetry_dataset() eq_sites = np.unique(ds['equivalent_atoms']) geomlines += [str(len(eq_sites))] for eq_site in eq_sites: site = struct.sites[eq_site] geomlines += [ "%s %s %s %s" % (site.specie.Z + 200, site.a, site.b, site.c) ] return geomlines, struct
def test_apply_transformation(self): trans = MagOrderingTransformation({"Fe": 5}) p = Poscar.from_file(os.path.join(test_dir, "POSCAR.LiFePO4"), check_for_POTCAR=False) s = p.structure alls = trans.apply_transformation(s, 10) self.assertEqual(len(alls), 3) f = SpacegroupAnalyzer(alls[0]["structure"], 0.1) self.assertEqual(f.get_spacegroup_number(), 31) model = IsingModel(5, 5) trans = MagOrderingTransformation({"Fe": 5}, energy_model=model) alls2 = trans.apply_transformation(s, 10) # Ising model with +J penalizes similar neighbor magmom. self.assertNotEqual(alls[0]["structure"], alls2[0]["structure"]) self.assertEqual(alls[0]["structure"], alls2[2]["structure"]) s = self.get_structure("Li2O") # Li2O doesn't have magnetism of course, but this is to test the # enumeration. trans = MagOrderingTransformation({"Li+": 1}, max_cell_size=3) alls = trans.apply_transformation(s, 100) self.assertEqual(len(alls), 10)
def set_output_data(self, d_calc, d): """ set the 'output' key """ d["output"] = { "structure": d_calc["output"]["structure"], "density": d_calc.pop("density"), "energy": d_calc["output"]["energy"], "energy_per_atom": d_calc["output"]["energy_per_atom"]} d["output"].update(self.get_basic_processed_data(d)) sg = SpacegroupAnalyzer(Structure.from_dict(d_calc["output"]["structure"]), 0.1) if not sg.get_symmetry_dataset(): sg = SpacegroupAnalyzer(Structure.from_dict(d_calc["output"]["structure"]), 1e-3, 1) d["output"]["spacegroup"] = { "source": "spglib", "symbol": sg.get_spacegroup_symbol(), "number": sg.get_spacegroup_number(), "point_group": sg.get_point_group(), "crystal_system": sg.get_crystal_system(), "hall": sg.get_hall()} if d["input"]["parameters"].get("LEPSILON"): for k in ['epsilon_static', 'epsilon_static_wolfe', 'epsilon_ionic']: d["output"][k] = d_calc["output"][k]
def test_apply_transformation(self): trans = MagOrderingTransformation({"Fe": 5}) p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'), check_for_POTCAR=False) s = p.structure alls = trans.apply_transformation(s, 10) self.assertEqual(len(alls), 3) f = SpacegroupAnalyzer(alls[0]["structure"], 0.1) self.assertEqual(f.get_spacegroup_number(), 31) model = IsingModel(5, 5) trans = MagOrderingTransformation({"Fe": 5}, energy_model=model) alls2 = trans.apply_transformation(s, 10) #Ising model with +J penalizes similar neighbor magmom. self.assertNotEqual(alls[0]["structure"], alls2[0]["structure"]) self.assertEqual(alls[0]["structure"], alls2[2]["structure"]) s = self.get_structure('Li2O') #Li2O doesn't have magnetism of course, but this is to test the # enumeration. trans = MagOrderingTransformation({"Li+": 1}, max_cell_size=3) alls = trans.apply_transformation(s, 100) self.assertEqual(len(alls), 10)
def get_sg_info(ss): finder = SpacegroupAnalyzer(Structure.from_sites(ss), self.symm_prec) sgnum = finder.get_spacegroup_number() return sgnum
def __init__(self, struct, find_spacegroup=False, symprec=None): """ Args: struct (Structure): structure to write find_spacegroup (bool): whether to try to determine the spacegroup symprec (float): If not none, finds the symmetry of the structure and writes the cif with symmetry information. Passes symprec to the SpacegroupAnalyzer """ format_str = "{:.8f}" block = OrderedDict() loops = [] latt = struct.lattice comp = struct.composition no_oxi_comp = comp.element_composition spacegroup = ("P 1", 1) if find_spacegroup: sf = SpacegroupAnalyzer(struct, 0.001) spacegroup = (sf.get_spacegroup_symbol(), sf.get_spacegroup_number()) block["_symmetry_space_group_name_H-M"] = spacegroup[0] for cell_attr in ['a', 'b', 'c']: block["_cell_length_" + cell_attr] = format_str.format( getattr(latt, cell_attr)) for cell_attr in ['alpha', 'beta', 'gamma']: block["_cell_angle_" + cell_attr] = format_str.format( getattr(latt, cell_attr)) block["_symmetry_Int_Tables_number"] = spacegroup[1] block["_chemical_formula_structural"] = no_oxi_comp.reduced_formula block["_chemical_formula_sum"] = no_oxi_comp.formula block["_cell_volume"] = latt.volume.__str__() reduced_comp = no_oxi_comp.reduced_composition el = no_oxi_comp.elements[0] amt = comp[el] fu = int(amt / reduced_comp[Element(el.symbol)]) block["_cell_formula_units_Z"] = str(fu) if symprec is None: block["_symmetry_equiv_pos_site_id"] = ["1"] block["_symmetry_equiv_pos_as_xyz"] = ["x, y, z"] else: sf = SpacegroupAnalyzer(struct, symprec) ops = [op.as_xyz_string() for op in sf.get_symmetry_operations()] block["_symmetry_equiv_pos_site_id"] = \ ["%d" % i for i in range(1, len(ops) + 1)] block["_symmetry_equiv_pos_as_xyz"] = ops loops.append( ["_symmetry_equiv_pos_site_id", "_symmetry_equiv_pos_as_xyz"]) contains_oxidation = True try: symbol_to_oxinum = OrderedDict([(el.__str__(), float(el.oxi_state)) for el in sorted(comp.elements)]) except AttributeError: symbol_to_oxinum = OrderedDict([(el.symbol, 0) for el in sorted(comp.elements)]) contains_oxidation = False if contains_oxidation: block["_atom_type_symbol"] = symbol_to_oxinum.keys() block["_atom_type_oxidation_number"] = symbol_to_oxinum.values() loops.append(["_atom_type_symbol", "_atom_type_oxidation_number"]) atom_site_type_symbol = [] atom_site_symmetry_multiplicity = [] atom_site_fract_x = [] atom_site_fract_y = [] atom_site_fract_z = [] atom_site_label = [] atom_site_occupancy = [] count = 1 if symprec is None: for site in struct: for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(sp.__str__()) atom_site_symmetry_multiplicity.append("1") atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(occu.__str__()) count += 1 else: for group in sf.get_symmetrized_structure().equivalent_sites: site = group[0] for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(sp.__str__()) atom_site_symmetry_multiplicity.append("%d" % len(group)) atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(occu.__str__()) count += 1 block["_atom_site_type_symbol"] = atom_site_type_symbol block["_atom_site_label"] = atom_site_label block["_atom_site_symmetry_multiplicity"] = \ atom_site_symmetry_multiplicity block["_atom_site_fract_x"] = atom_site_fract_x block["_atom_site_fract_y"] = atom_site_fract_y block["_atom_site_fract_z"] = atom_site_fract_z block["_atom_site_occupancy"] = atom_site_occupancy loops.append([ "_atom_site_type_symbol", "_atom_site_label", "_atom_site_symmetry_multiplicity", "_atom_site_fract_x", "_atom_site_fract_y", "_atom_site_fract_z", "_atom_site_occupancy" ]) d = OrderedDict() d[comp.reduced_formula] = CifBlock(block, loops, comp.reduced_formula) self._cf = CifFile(d)
def analyze(args): """analyze data at any point for a copy of the streaming figure""" # NOTE: make copy online first with suffix _%Y-%m-%d and note figure id fig = py.get_figure(creds['username'], args.fig_id) if args.t: if args.fig_id == 42: label_entries = filter(None, '<br>'.join(fig['data'][2]['text']).split('<br>')) pairs = map(make_tuple, label_entries) grps = set(chain.from_iterable(pairs)) snlgrp_cursor = sma.snlgroups.aggregate([ { '$match': { 'snlgroup_id': { '$in': list(grps) }, 'canonical_snl.about.projects': {'$ne': 'CederDahn Challenge'} } }, { '$project': { 'snlgroup_id': 1, 'canonical_snl.snlgroup_key': 1, '_id': 0 } } ], cursor={}) snlgroup_keys = {} for d in snlgrp_cursor: snlgroup_keys[d['snlgroup_id']] = d['canonical_snl']['snlgroup_key'] print snlgroup_keys[40890] sma2 = SNLMongoAdapter.from_file( os.path.join(os.environ['DB_LOC'], 'materials_db.yaml') ) materials_cursor = sma2.database.materials.aggregate([ { '$match': { 'snlgroup_id_final': { '$in': list(grps) }, 'snl_final.about.projects': {'$ne': 'CederDahn Challenge'} } }, { '$project': { 'snlgroup_id_final': 1, '_id': 0, 'task_id': 1, 'final_energy_per_atom': 1, 'band_gap.search_gap.band_gap': 1, 'volume': 1, 'nsites': 1 }} ], cursor={}) snlgroup_data = {} for material in materials_cursor: snlgroup_id = material['snlgroup_id_final'] final_energy_per_atom = material['final_energy_per_atom'] band_gap = material['band_gap']['search_gap']['band_gap'] volume_per_atom = material['volume'] / material['nsites'] snlgroup_data[snlgroup_id] = { 'final_energy_per_atom': final_energy_per_atom, 'band_gap': band_gap, 'task_id': material['task_id'], 'volume_per_atom': volume_per_atom } print snlgroup_data[40890] filestem = 'mpworks/check_snl/results/bad_snlgroups_2_' with open(filestem+'in_matdb.csv', 'wb') as f, \ open(filestem+'notin_matdb.csv', 'wb') as g: writer1, writer2 = csv.writer(f), csv.writer(g) header = [ 'category', 'composition', 'snlgroup_id 1', 'sg_num 1', 'task_id 1', 'snlgroup_id 2', 'sg_num 2', 'task_id 2', 'delta_energy', 'delta_bandgap', 'delta_volume_per_atom', 'rms_dist', 'scenario' ] writer1.writerow(header) writer2.writerow(header) for primary_id, secondary_id in pairs: if primary_id not in snlgroup_keys or \ secondary_id not in snlgroup_keys: continue composition, primary_sg_num = snlgroup_keys[primary_id].split('--') secondary_sg_num = snlgroup_keys[secondary_id].split('--')[1] category = 'same SGs' if primary_sg_num == secondary_sg_num else 'diff. SGs' if primary_id not in snlgroup_data or secondary_id not in snlgroup_data: delta_energy, delta_bandgap, delta_volume_per_atom = '', '', '' else: delta_energy = "{0:.3g}".format(abs( snlgroup_data[primary_id]['final_energy_per_atom'] - \ snlgroup_data[secondary_id]['final_energy_per_atom'] )) delta_bandgap = "{0:.3g}".format(abs( snlgroup_data[primary_id]['band_gap'] - \ snlgroup_data[secondary_id]['band_gap'] )) delta_volume_per_atom = "{0:.3g}".format(abs( snlgroup_data[primary_id]['volume_per_atom'] - \ snlgroup_data[secondary_id]['volume_per_atom'] )) scenario, rms_dist_str = '', '' if category == 'diff. SGs' and delta_energy and delta_bandgap: scenario = 'different' if ( float(delta_energy) > 0.01 or float(delta_bandgap) > 0.1 ) else 'similar' snlgrp1_dict = sma.snlgroups.find_one({ "snlgroup_id": primary_id }) snlgrp2_dict = sma.snlgroups.find_one({ "snlgroup_id": secondary_id }) snlgrp1 = SNLGroup.from_dict(snlgrp1_dict) snlgrp2 = SNLGroup.from_dict(snlgrp2_dict) primary_structure = snlgrp1.canonical_structure secondary_structure = snlgrp2.canonical_structure rms_dist = matcher.get_rms_dist(primary_structure, secondary_structure) if rms_dist is not None: rms_dist_str = "({0:.3g},{1:.3g})".format(*rms_dist) print rms_dist_str row = [ category, composition, primary_id, primary_sg_num, snlgroup_data[primary_id]['task_id'] \ if primary_id in snlgroup_data else '', secondary_id, secondary_sg_num, snlgroup_data[secondary_id]['task_id'] \ if secondary_id in snlgroup_data else '', delta_energy, delta_bandgap, delta_volume_per_atom, rms_dist_str, scenario ] if delta_energy and delta_bandgap: writer1.writerow(row) else: writer2.writerow(row) elif args.fig_id == 16: out_fig = Figure() badsnls_trace = Scatter(x=[], y=[], text=[], mode='markers', name='SG Changes') bisectrix = Scatter(x=[0,230], y=[0,230], mode='lines', name='bisectrix') print 'pulling bad snls from plotly ...' bad_snls = OrderedDict() for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']): for snl_id in map(int, text.split('<br>')): bad_snls[snl_id] = category with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f: print 'pulling bad snls from database ...' mpsnl_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snls.keys() }, 'about.projects': {'$ne': 'CederDahn Challenge'} }) writer = csv.writer(f) writer.writerow([ 'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors' ]) print 'writing bad snls to file ...' for mpsnl_dict in mpsnl_cursor: mpsnl = MPStructureNL.from_dict(mpsnl_dict) row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ] row += _get_snl_extra_info(mpsnl) writer.writerow(row) sg_num = mpsnl.snlgroup_key.split('--')[1] if (bad_snls[mpsnl.snl_id] == 'SG default' and sg_num != '-1') or \ bad_snls[mpsnl.snl_id] == 'SG change': mpsnl.structure.remove_oxidation_states() sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1) badsnls_trace['x'].append(mpsnl.sg_num) badsnls_trace['y'].append(sf.get_spacegroup_number()) badsnls_trace['text'].append(mpsnl.snl_id) if bad_snls[mpsnl.snl_id] == 'SG default': print sg_num, sf.get_spacegroup_number() print 'plotting out-fig ...' out_fig['data'] = Data([bisectrix, badsnls_trace]) out_fig['layout'] = Layout( showlegend=False, hovermode='closest', title='Spacegroup Assignment Changes', xaxis=XAxis(showgrid=False, title='old SG number', range=[0,230]), yaxis=YAxis(showgrid=False, title='new SG number', range=[0,230]), ) filename = 'spacegroup_changes_' filename += datetime.datetime.now().strftime('%Y-%m-%d') py.plot(out_fig, filename=filename, auto_open=False) elif args.fig_id == 43: # SNLGroupMemberChecker matcher2 = StructureMatcher( ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, comparator=ElementComparator() ) print 'pulling data from plotly ...' trace = Scatter(x=[], y=[], text=[], mode='markers', name='mismatches') bad_snls = OrderedDict() # snlgroup_id : [ mismatching snl_ids ] for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']): if category != 'mismatch': continue for entry in text.split('<br>'): fields = entry.split(':') snlgroup_id = int(fields[0].split(',')[0]) print snlgroup_id snlgrp_dict = sma.snlgroups.find_one({ 'snlgroup_id': snlgroup_id }) snlgrp = SNLGroup.from_dict(snlgrp_dict) s1 = snlgrp.canonical_structure.get_primitive_structure() bad_snls[snlgroup_id] = [] for i, snl_id in enumerate(fields[1].split(',')): mpsnl_dict = sma.snl.find_one({ 'snl_id': int(snl_id) }) if 'CederDahn Challenge' in mpsnl_dict['about']['projects']: print 'skip CederDahn: %s' % snl_id continue mpsnl = MPStructureNL.from_dict(mpsnl_dict) s2 = mpsnl.structure.get_primitive_structure() is_match = matcher2.fit(s1, s2) if is_match: continue bad_snls[snlgroup_id].append(snl_id) trace['x'].append(snlgroup_id) trace['y'].append(i+1) trace['text'].append(snl_id) if len(bad_snls[snlgroup_id]) < 1: bad_snls.pop(snlgroup_id, None) with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f: print 'pulling bad snlgroups from database ...' snlgroup_cursor = sma.snlgroups.find({ 'snlgroup_id': { '$in': bad_snls.keys() }, }) writer = csv.writer(f) writer.writerow(['snlgroup_id', 'snlgroup_key', 'mismatching snl_ids']) print 'writing bad snlgroups to file ...' for snlgroup_dict in snlgroup_cursor: snlgroup = SNLGroup.from_dict(snlgroup_dict) row = [ snlgroup.snlgroup_id, snlgroup.canonical_snl.snlgroup_key, ' '.join(bad_snls[snlgroup.snlgroup_id]) ] writer.writerow(row) print 'plotting out-fig ...' out_fig = Figure() out_fig['data'] = Data([trace]) out_fig['layout'] = Layout( showlegend=False, hovermode='closest', title='Member Mismatches of SNLGroup Canonicals', xaxis=XAxis(showgrid=False, title='snlgroup_id', showexponent='none'), yaxis=YAxis(showgrid=False, title='# mismatching SNLs'), ) filename = 'groupmember_mismatches_' filename += datetime.datetime.now().strftime('%Y-%m-%d') py.plot(out_fig, filename=filename, auto_open=False) else: errors = Counter() bad_snls = OrderedDict() bad_snlgroups = OrderedDict() for i,d in enumerate(fig['data']): if not isinstance(d, Scatter): continue if not 'x' in d or not 'y' in d or not 'text' in d: continue start_id = int(d['name'].split(' - ')[0][:-1])*1000 marker_colors = d['marker']['color'] if i < 2*num_snl_streams: # spacegroups errors += Counter(marker_colors) for idx,color in enumerate(marker_colors): snl_id = start_id + d['x'][idx] color_index = category_colors.index(color) category = categories[color_index] bad_snls[snl_id] = category else: # groupmembers for idx,color in enumerate(marker_colors): if color != category_colors[0]: continue snlgroup_id = start_id + d['x'][idx] mismatch_snl_id, canonical_snl_id = d['text'][idx].split(' != ') bad_snlgroups[snlgroup_id] = int(mismatch_snl_id) print errors fig_data = fig['data'][-1] fig_data['x'] = [ errors[color] for color in fig_data['marker']['color'] ] filename = _get_filename() print filename #py.plot(fig, filename=filename) with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f: mpsnl_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snls.keys() } }) writer = csv.writer(f) writer.writerow([ 'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors' ]) for mpsnl_dict in mpsnl_cursor: mpsnl = MPStructureNL.from_dict(mpsnl_dict) row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ] row += _get_snl_extra_info(mpsnl) writer.writerow(row) with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f: snlgrp_cursor = sma.snlgroups.find({ 'snlgroup_id': { '$in': bad_snlgroups.keys() } }) first_mismatch_snls_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snlgroups.values() } }) first_mismatch_snl_info = OrderedDict() for mpsnl_dict in first_mismatch_snls_cursor: mpsnl = MPStructureNL.from_dict(mpsnl_dict) first_mismatch_snl_info[mpsnl.snl_id] = _get_snl_extra_info(mpsnl) writer = csv.writer(f) writer.writerow([ 'snlgroup_id', 'snlgroup_key', 'canonical_snl_id', 'first_mismatching_snl_id', 'nsites', 'remarks', 'projects', 'authors' ]) for snlgrp_dict in snlgrp_cursor: snlgrp = SNLGroup.from_dict(snlgrp_dict) first_mismatch_snl_id = bad_snlgroups[snlgrp.snlgroup_id] row = [ snlgrp.snlgroup_id, snlgrp.canonical_snl.snlgroup_key, snlgrp.canonical_snl.snl_id, first_mismatch_snl_id ] row += [ ' & '.join(pair) if pair[0] != pair[1] else pair[0] for pair in zip( _get_snl_extra_info(snlgrp.canonical_snl), first_mismatch_snl_info[int(first_mismatch_snl_id)] ) ] writer.writerow(row)
def _gen_input_file(self): """ Generate the necessary struct_enum.in file for enumlib. See enumlib documentation for details. """ coord_format = "{:.6f} {:.6f} {:.6f}" # Using symmetry finder, get the symmetrically distinct sites. fitter = SpacegroupAnalyzer(self.structure, self.symm_prec) symmetrized_structure = fitter.get_symmetrized_structure() logger.debug("Spacegroup {} ({}) with {} distinct sites".format( fitter.get_spacegroup_symbol(), fitter.get_spacegroup_number(), len(symmetrized_structure.equivalent_sites)) ) """ Enumlib doesn"t work when the number of species get too large. To simplify matters, we generate the input file only with disordered sites and exclude the ordered sites from the enumeration. The fact that different disordered sites with the exact same species may belong to different equivalent sites is dealt with by having determined the spacegroup earlier and labelling the species differently. """ # index_species and index_amounts store mappings between the indices # used in the enum input file, and the actual species and amounts. index_species = [] index_amounts = [] #Stores the ordered sites, which are not enumerated. ordered_sites = [] disordered_sites = [] coord_str = [] for sites in symmetrized_structure.equivalent_sites: if sites[0].is_ordered: ordered_sites.append(sites) else: sp_label = [] species = {k: v for k, v in sites[0].species_and_occu.items()} if sum(species.values()) < 1 - EnumlibAdaptor.amount_tol: #Let us first make add a dummy element for every single #site whose total occupancies don't sum to 1. species[DummySpecie("X")] = 1 - sum(species.values()) for sp in species.keys(): if sp not in index_species: index_species.append(sp) sp_label.append(len(index_species) - 1) index_amounts.append(species[sp] * len(sites)) else: ind = index_species.index(sp) sp_label.append(ind) index_amounts[ind] += species[sp] * len(sites) sp_label = "/".join(["{}".format(i) for i in sorted(sp_label)]) for site in sites: coord_str.append("{} {}".format( coord_format.format(*site.coords), sp_label)) disordered_sites.append(sites) def get_sg_info(ss): finder = SpacegroupAnalyzer(Structure.from_sites(ss), self.symm_prec) sgnum = finder.get_spacegroup_number() return sgnum curr_sites = list(itertools.chain.from_iterable(disordered_sites)) min_sgnum = get_sg_info(curr_sites) logger.debug("Disorderd sites has sgnum %d" % ( min_sgnum)) #It could be that some of the ordered sites has a lower symmetry than #the disordered sites. So we consider the lowest symmetry sites as #disordered in our enumeration. self.ordered_sites = [] to_add = [] if self.check_ordered_symmetry: for sites in ordered_sites: temp_sites = list(curr_sites) + sites sgnum = get_sg_info(temp_sites) if sgnum < min_sgnum: logger.debug("Adding {} to sites to be ordered. " "New sgnum {}" .format(sites, sgnum)) to_add = sites min_sgnum = sgnum for sites in ordered_sites: if sites == to_add: index_species.append(sites[0].specie) index_amounts.append(len(sites)) sp_label = len(index_species) - 1 logger.debug("Lowest symmetry {} sites are included in enum." .format(sites[0].specie)) for site in sites: coord_str.append("{} {}".format( coord_format.format(*site.coords), sp_label)) disordered_sites.append(sites) else: self.ordered_sites.extend(sites) self.index_species = index_species lattice = self.structure.lattice output = [self.structure.formula, "bulk"] for vec in lattice.matrix: output.append(coord_format.format(*vec)) output.append("{}".format(len(index_species))) output.append("{}".format(len(coord_str))) output.extend(coord_str) output.append("{} {}".format(self.min_cell_size, self.max_cell_size)) output.append(str(self.enum_precision_parameter)) output.append("partial") ndisordered = sum([len(s) for s in disordered_sites]) base = int(ndisordered*reduce(lcm, [f.limit_denominator( ndisordered * self.max_cell_size).denominator for f in map(fractions.Fraction, index_amounts)])) #base = ndisordered #10 ** int(math.ceil(math.log10(ndisordered))) #To get a reasonable number of structures, we fix concentrations to the #range expected in the original structure. total_amounts = sum(index_amounts) for amt in index_amounts: conc = amt / total_amounts if abs(conc * base - round(conc * base)) < 1e-5: output.append("{} {} {}".format(int(round(conc * base)), int(round(conc * base)), base)) else: min_conc = int(math.floor(conc * base)) output.append("{} {} {}".format(min_conc - 1, min_conc + 1, base)) output.append("") logger.debug("Generated input file:\n{}".format("\n".join(output))) with open("struct_enum.in", "w") as f: f.write("\n".join(output))
def get_energy(self, structure): f = SpacegroupAnalyzer(structure, symprec=self.symprec, angle_tolerance=self.angle_tolerance) return -f.get_spacegroup_number()
def get_sg(s): finder = SpacegroupAnalyzer(s, symprec=self._symprec) return finder.get_spacegroup_number()
def generate_doc(self, dir_name, vasprun_files): """ Overridden """ try: fullpath = os.path.abspath(dir_name) d = {k: v for k, v in self.additional_fields.items()} d["dir_name"] = fullpath d["schema_version"] = VaspToDbTaskDrone.__version__ d["calculations"] = [ self.process_vasprun(dir_name, taskname, filename) for taskname, filename in vasprun_files.items() ] d1 = d["calculations"][0] d2 = d["calculations"][-1] # Now map some useful info to the root level. for root_key in [ "completed_at", "nsites", "unit_cell_formula", "reduced_cell_formula", "pretty_formula", "elements", "nelements", "cif", "density", "is_hubbard", "hubbards", "run_type" ]: d[root_key] = d2[root_key] d["chemsys"] = "-".join(sorted(d2["elements"])) # store any overrides to the exchange correlation functional xc = d2["input"]["incar"].get("GGA") if xc: xc = xc.upper() d["input"] = { "crystal": d1["input"]["crystal"], "is_lasph": d2["input"]["incar"].get("LASPH", False), "potcar_spec": d1["input"].get("potcar_spec"), "xc_override": xc } vals = sorted(d2["reduced_cell_formula"].values()) d["anonymous_formula"] = { string.ascii_uppercase[i]: float(vals[i]) for i in range(len(vals)) } d["output"] = { "crystal": d2["output"]["crystal"], "final_energy": d2["output"]["final_energy"], "final_energy_per_atom": d2["output"]["final_energy_per_atom"] } d["name"] = "vasp" p = d2["input"]["potcar_type"][0].split("_") pot_type = p[0] functional = "lda" if len(pot_type) == 1 else "_".join(p[1:]) d["pseudo_potential"] = { "functional": functional.lower(), "pot_type": pot_type.lower(), "labels": d2["input"]["potcar"] } if len(d["calculations"]) == len(self.runs) or \ list(vasprun_files.keys())[0] != "relax1": d["state"] = "successful" if d2["has_vasp_completed"] \ else "unsuccessful" else: d["state"] = "stopped" d["analysis"] = analysis_and_error_checks(d) sg = SpacegroupAnalyzer( Structure.from_dict(d["output"]["crystal"]), 0.1) d["spacegroup"] = { "symbol": sg.get_spacegroup_symbol(), "number": sg.get_spacegroup_number(), "point_group": sg.get_point_group(), "source": "spglib", "crystal_system": sg.get_crystal_system(), "hall": sg.get_hall() } d["last_updated"] = datetime.datetime.today() return d except Exception as ex: import traceback print(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) return None
def __init__(self, struct, symprec=None): format_str = "{:.8f}" block = OrderedDict() loops = [] spacegroup = ("P 1", 1) if symprec is not None: sf = SpacegroupAnalyzer(struct, symprec) spacegroup = (sf.get_spacegroup_symbol(), sf.get_spacegroup_number()) # Needs the refined struture when using symprec. This converts # primitive to conventional structures, the standard for CIF. struct = sf.get_refined_structure() latt = struct.lattice comp = struct.composition no_oxi_comp = comp.element_composition block["_symmetry_space_group_name_H-M"] = spacegroup[0] for cell_attr in ['a', 'b', 'c']: block["_cell_length_" + cell_attr] = format_str.format( getattr(latt, cell_attr)) for cell_attr in ['alpha', 'beta', 'gamma']: block["_cell_angle_" + cell_attr] = format_str.format( getattr(latt, cell_attr)) block["_symmetry_Int_Tables_number"] = spacegroup[1] block["_chemical_formula_structural"] = no_oxi_comp.reduced_formula block["_chemical_formula_sum"] = no_oxi_comp.formula block["_cell_volume"] = latt.volume.__str__() reduced_comp, fu = no_oxi_comp.get_reduced_composition_and_factor() block["_cell_formula_units_Z"] = str(int(fu)) if symprec is None: block["_symmetry_equiv_pos_site_id"] = ["1"] block["_symmetry_equiv_pos_as_xyz"] = ["x, y, z"] else: sf = SpacegroupAnalyzer(struct, symprec) def round_symm_trans(i): for t in TRANSLATIONS.values(): if abs(i - t) < symprec: return t if abs(i - round(i)) < symprec: return 0 raise ValueError("Invalid translation!") symmops = [] for op in sf.get_symmetry_operations(): v = op.translation_vector v = [round_symm_trans(i) for i in v] symmops.append( SymmOp.from_rotation_and_translation( op.rotation_matrix, v)) ops = [op.as_xyz_string() for op in symmops] block["_symmetry_equiv_pos_site_id"] = \ ["%d" % i for i in range(1, len(ops) + 1)] block["_symmetry_equiv_pos_as_xyz"] = ops loops.append( ["_symmetry_equiv_pos_site_id", "_symmetry_equiv_pos_as_xyz"]) contains_oxidation = True try: symbol_to_oxinum = OrderedDict([(el.__str__(), float(el.oxi_state)) for el in sorted(comp.elements)]) except AttributeError: symbol_to_oxinum = OrderedDict([(el.symbol, 0) for el in sorted(comp.elements)]) contains_oxidation = False if contains_oxidation: block["_atom_type_symbol"] = symbol_to_oxinum.keys() block["_atom_type_oxidation_number"] = symbol_to_oxinum.values() loops.append(["_atom_type_symbol", "_atom_type_oxidation_number"]) atom_site_type_symbol = [] atom_site_symmetry_multiplicity = [] atom_site_fract_x = [] atom_site_fract_y = [] atom_site_fract_z = [] atom_site_label = [] atom_site_occupancy = [] count = 1 if symprec is None: for site in struct: for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(sp.__str__()) atom_site_symmetry_multiplicity.append("1") atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(occu.__str__()) count += 1 else: # The following just presents a deterministic ordering. unique_sites = [ (sorted(sites, key=lambda s: tuple([abs(x) for x in s.frac_coords]))[0], len(sites)) for sites in sf.get_symmetrized_structure().equivalent_sites ] for site, mult in sorted(unique_sites, key=lambda t: (t[0].species_and_occu.average_electroneg, -t[1], t[0].a, t[0].b, t[0].c)): for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(sp.__str__()) atom_site_symmetry_multiplicity.append("%d" % mult) atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(occu.__str__()) count += 1 block["_atom_site_type_symbol"] = atom_site_type_symbol block["_atom_site_label"] = atom_site_label block["_atom_site_symmetry_multiplicity"] = \ atom_site_symmetry_multiplicity block["_atom_site_fract_x"] = atom_site_fract_x block["_atom_site_fract_y"] = atom_site_fract_y block["_atom_site_fract_z"] = atom_site_fract_z block["_atom_site_occupancy"] = atom_site_occupancy loops.append([ "_atom_site_type_symbol", "_atom_site_label", "_atom_site_symmetry_multiplicity", "_atom_site_fract_x", "_atom_site_fract_y", "_atom_site_fract_z", "_atom_site_occupancy" ]) d = OrderedDict() d[comp.reduced_formula] = CifBlock(block, loops, comp.reduced_formula) self._cf = CifFile(d)
class SpacegroupAnalyzerTest(PymatgenTest): def setUp(self): p = Poscar.from_file(os.path.join(test_dir, 'POSCAR')) self.structure = p.structure self.sg = SpacegroupAnalyzer(self.structure, 0.001) self.disordered_structure = self.get_structure('Li10GeP2S12') self.disordered_sg = SpacegroupAnalyzer(self.disordered_structure, 0.001) s = p.structure.copy() site = s[0] del s[0] s.append(site.species_and_occu, site.frac_coords) self.sg3 = SpacegroupAnalyzer(s, 0.001) graphite = self.get_structure('Graphite') graphite.add_site_property("magmom", [0.1] * len(graphite)) self.sg4 = SpacegroupAnalyzer(graphite, 0.001) def test_get_space_symbol(self): self.assertEqual(self.sg.get_spacegroup_symbol(), "Pnma") self.assertEqual(self.disordered_sg.get_spacegroup_symbol(), "P4_2/nmc") self.assertEqual(self.sg3.get_spacegroup_symbol(), "Pnma") self.assertEqual(self.sg4.get_spacegroup_symbol(), "P6_3/mmc") def test_get_space_number(self): self.assertEqual(self.sg.get_spacegroup_number(), 62) self.assertEqual(self.disordered_sg.get_spacegroup_number(), 137) self.assertEqual(self.sg4.get_spacegroup_number(), 194) def test_get_hall(self): self.assertEqual(self.sg.get_hall(), '-P 2ac 2n') self.assertEqual(self.disordered_sg.get_hall(), 'P 4n 2n -1n') def test_get_pointgroup(self): self.assertEqual(self.sg.get_point_group(), 'mmm') self.assertEqual(self.disordered_sg.get_point_group(), '4/mmm') def test_get_symmetry_dataset(self): ds = self.sg.get_symmetry_dataset() self.assertEqual(ds['international'], 'Pnma') def test_get_crystal_system(self): crystal_system = self.sg.get_crystal_system() self.assertEqual('orthorhombic', crystal_system) self.assertEqual('tetragonal', self.disordered_sg.get_crystal_system()) def test_get_symmetry_operations(self): fracsymmops = self.sg.get_symmetry_operations() symmops = self.sg.get_symmetry_operations(True) self.assertEqual(len(symmops), 8) latt = self.structure.lattice for fop, op in zip(fracsymmops, symmops): for site in self.structure: newfrac = fop.operate(site.frac_coords) newcart = op.operate(site.coords) self.assertTrue(np.allclose(latt.get_fractional_coords(newcart), newfrac)) found = False newsite = PeriodicSite(site.species_and_occu, newcart, latt, coords_are_cartesian=True) for testsite in self.structure: if newsite.is_periodic_image(testsite, 1e-3): found = True break self.assertTrue(found) def test_get_refined_structure(self): for a in self.sg.get_refined_structure().lattice.angles: self.assertEqual(a, 90) refined = self.disordered_sg.get_refined_structure() for a in refined.lattice.angles: self.assertEqual(a, 90) self.assertEqual(refined.lattice.a, refined.lattice.b) s = self.get_structure('Li2O') sg = SpacegroupAnalyzer(s, 0.001) self.assertEqual(sg.get_refined_structure().num_sites, 4 * s.num_sites) def test_get_symmetrized_structure(self): symm_struct = self.sg.get_symmetrized_structure() for a in symm_struct.lattice.angles: self.assertEqual(a, 90) self.assertEqual(len(symm_struct.equivalent_sites), 5) symm_struct = self.disordered_sg.get_symmetrized_structure() self.assertEqual(len(symm_struct.equivalent_sites), 8) self.assertEqual([len(i) for i in symm_struct.equivalent_sites], [16,4,8,4,2,8,8,8]) s1 = symm_struct.equivalent_sites[1][1] s2 = symm_struct[symm_struct.equivalent_indices[1][1]] self.assertEqual(s1, s2) self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1) def test_find_primitive(self): """ F m -3 m Li2O testing of converting to primitive cell """ parser = CifParser(os.path.join(test_dir, 'Li2O.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure) primitive_structure = s.find_primitive() self.assertEqual(primitive_structure.formula, "Li2 O1") # This isn't what is expected. All the angles should be 60 self.assertAlmostEqual(primitive_structure.lattice.alpha, 60) self.assertAlmostEqual(primitive_structure.lattice.beta, 60) self.assertAlmostEqual(primitive_structure.lattice.gamma, 60) self.assertAlmostEqual(primitive_structure.lattice.volume, structure.lattice.volume / 4.0) def test_get_ir_reciprocal_mesh(self): grid=self.sg.get_ir_reciprocal_mesh() self.assertEqual(len(grid), 216) self.assertAlmostEquals(grid[1][0][0], 0.1) self.assertAlmostEquals(grid[1][0][1], 0.0) self.assertAlmostEquals(grid[1][0][2], 0.0) self.assertEqual(grid[1][1], 2) def test_get_conventional_standard_structure(self): parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461) self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461) self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461) parser = CifParser(os.path.join(test_dir, 'btet_1915.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235) self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235) self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687) parser = CifParser(os.path.join(test_dir, 'orci_1010.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999) self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296) self.assertAlmostEqual(conv.lattice.c, 5.373703587040775) parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998) self.assertAlmostEqual(conv.lattice.b, 31.437979757624728) self.assertAlmostEqual(conv.lattice.c, 3.99648651) parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 14.033435583000625) self.assertAlmostEqual(conv.lattice.b, 3.96052850731) self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002) parser = CifParser(os.path.join(test_dir, 'hex_1170.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 120) self.assertAlmostEqual(conv.lattice.a, 3.699919902005897) self.assertAlmostEqual(conv.lattice.b, 3.699919902005897) self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003) def test_get_primitive_standard_structure(self): parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001) self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001) self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001) self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145) parser = CifParser(os.path.join(test_dir, 'btet_1915.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 105.015053349) self.assertAlmostEqual(prim.lattice.beta, 105.015053349) self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999) self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791) parser = CifParser(os.path.join(test_dir, 'orci_1010.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001) self.assertAlmostEqual(prim.lattice.beta, 105.856239333) self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001) self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852) parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 164.985257335) self.assertAlmostEqual(prim.lattice.a, 15.854897098324196) self.assertAlmostEqual(prim.lattice.b, 15.854897098324196) self.assertAlmostEqual(prim.lattice.c, 3.99648651) parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999) self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779) self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569) self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002) parser = CifParser(os.path.join(test_dir, 'hex_1170.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 120) self.assertAlmostEqual(prim.lattice.a, 3.699919902005897) self.assertAlmostEqual(prim.lattice.b, 3.699919902005897) self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003) parser = CifParser(os.path.join(test_dir, 'rhomb_3478_conv.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 28.049186140546812) self.assertAlmostEqual(prim.lattice.beta, 28.049186140546812) self.assertAlmostEqual(prim.lattice.gamma, 28.049186140546812) self.assertAlmostEqual(prim.lattice.a, 5.9352627428399982) self.assertAlmostEqual(prim.lattice.b, 5.9352627428399982) self.assertAlmostEqual(prim.lattice.c, 5.9352627428399982)
##http://pymatgen.org/_static/Basic%20functionality.html import pymatgen as mg from pymatgen.io.aseio import AseAtomsAdaptor from pymatgen.symmetry.analyzer import SpacegroupAnalyzer #si = mg.Element("Si") #print("Atomic mass of Si is {}".format(si.atomic_mass)) #print("Si has a melting point of {}".format(si.melting_point)) #print("Ionic radii for Si: {}".format(si.ionic_radii)) ###################################################### structure = mg.Structure.from_file("POSCAR") finder = SpacegroupAnalyzer(structure) num = finder.get_spacegroup_number() print(num) ase_atoms = AseAtomsAdaptor().get_atoms(structure) import ase.io.vasp ase.io.vasp.write_vasp('ase_atoms', ase_atoms, direct=False)
def get_energy(self, structure): f = SpacegroupAnalyzer(structure, symprec=self.symprec, angle_tolerance=self.angle_tolerance) return -f.get_spacegroup_number()
def analyze(args): """analyze data at any point for a copy of the streaming figure""" # NOTE: make copy online first with suffix _%Y-%m-%d and note figure id fig = py.get_figure(creds['username'], args.fig_id) if args.t: if args.fig_id == 42: label_entries = filter( None, '<br>'.join(fig['data'][2]['text']).split('<br>')) pairs = map(make_tuple, label_entries) grps = set(chain.from_iterable(pairs)) snlgrp_cursor = sma.snlgroups.aggregate([{ '$match': { 'snlgroup_id': { '$in': list(grps) }, 'canonical_snl.about.projects': { '$ne': 'CederDahn Challenge' } } }, { '$project': { 'snlgroup_id': 1, 'canonical_snl.snlgroup_key': 1, '_id': 0 } }], cursor={}) snlgroup_keys = {} for d in snlgrp_cursor: snlgroup_keys[ d['snlgroup_id']] = d['canonical_snl']['snlgroup_key'] print snlgroup_keys[40890] sma2 = SNLMongoAdapter.from_file( os.path.join(os.environ['DB_LOC'], 'materials_db.yaml')) materials_cursor = sma2.database.materials.aggregate([{ '$match': { 'snlgroup_id_final': { '$in': list(grps) }, 'snl_final.about.projects': { '$ne': 'CederDahn Challenge' } } }, { '$project': { 'snlgroup_id_final': 1, '_id': 0, 'task_id': 1, 'final_energy_per_atom': 1, 'band_gap.search_gap.band_gap': 1, 'volume': 1, 'nsites': 1 } }], cursor={}) snlgroup_data = {} for material in materials_cursor: snlgroup_id = material['snlgroup_id_final'] final_energy_per_atom = material['final_energy_per_atom'] band_gap = material['band_gap']['search_gap']['band_gap'] volume_per_atom = material['volume'] / material['nsites'] snlgroup_data[snlgroup_id] = { 'final_energy_per_atom': final_energy_per_atom, 'band_gap': band_gap, 'task_id': material['task_id'], 'volume_per_atom': volume_per_atom } print snlgroup_data[40890] filestem = 'mpworks/check_snl/results/bad_snlgroups_2_' with open(filestem+'in_matdb.csv', 'wb') as f, \ open(filestem+'notin_matdb.csv', 'wb') as g: writer1, writer2 = csv.writer(f), csv.writer(g) header = [ 'category', 'composition', 'snlgroup_id 1', 'sg_num 1', 'task_id 1', 'snlgroup_id 2', 'sg_num 2', 'task_id 2', 'delta_energy', 'delta_bandgap', 'delta_volume_per_atom', 'rms_dist', 'scenario' ] writer1.writerow(header) writer2.writerow(header) for primary_id, secondary_id in pairs: if primary_id not in snlgroup_keys or \ secondary_id not in snlgroup_keys: continue composition, primary_sg_num = snlgroup_keys[ primary_id].split('--') secondary_sg_num = snlgroup_keys[secondary_id].split( '--')[1] category = 'same SGs' if primary_sg_num == secondary_sg_num else 'diff. SGs' if primary_id not in snlgroup_data or secondary_id not in snlgroup_data: delta_energy, delta_bandgap, delta_volume_per_atom = '', '', '' else: delta_energy = "{0:.3g}".format(abs( snlgroup_data[primary_id]['final_energy_per_atom'] - \ snlgroup_data[secondary_id]['final_energy_per_atom'] )) delta_bandgap = "{0:.3g}".format(abs( snlgroup_data[primary_id]['band_gap'] - \ snlgroup_data[secondary_id]['band_gap'] )) delta_volume_per_atom = "{0:.3g}".format(abs( snlgroup_data[primary_id]['volume_per_atom'] - \ snlgroup_data[secondary_id]['volume_per_atom'] )) scenario, rms_dist_str = '', '' if category == 'diff. SGs' and delta_energy and delta_bandgap: scenario = 'different' if ( float(delta_energy) > 0.01 or float(delta_bandgap) > 0.1) else 'similar' snlgrp1_dict = sma.snlgroups.find_one( {"snlgroup_id": primary_id}) snlgrp2_dict = sma.snlgroups.find_one( {"snlgroup_id": secondary_id}) snlgrp1 = SNLGroup.from_dict(snlgrp1_dict) snlgrp2 = SNLGroup.from_dict(snlgrp2_dict) primary_structure = snlgrp1.canonical_structure secondary_structure = snlgrp2.canonical_structure rms_dist = matcher.get_rms_dist( primary_structure, secondary_structure) if rms_dist is not None: rms_dist_str = "({0:.3g},{1:.3g})".format( *rms_dist) print rms_dist_str row = [ category, composition, primary_id, primary_sg_num, snlgroup_data[primary_id]['task_id'] \ if primary_id in snlgroup_data else '', secondary_id, secondary_sg_num, snlgroup_data[secondary_id]['task_id'] \ if secondary_id in snlgroup_data else '', delta_energy, delta_bandgap, delta_volume_per_atom, rms_dist_str, scenario ] if delta_energy and delta_bandgap: writer1.writerow(row) else: writer2.writerow(row) elif args.fig_id == 16: out_fig = Figure() badsnls_trace = Scatter(x=[], y=[], text=[], mode='markers', name='SG Changes') bisectrix = Scatter(x=[0, 230], y=[0, 230], mode='lines', name='bisectrix') print 'pulling bad snls from plotly ...' bad_snls = OrderedDict() for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']): for snl_id in map(int, text.split('<br>')): bad_snls[snl_id] = category with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f: print 'pulling bad snls from database ...' mpsnl_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snls.keys() }, 'about.projects': { '$ne': 'CederDahn Challenge' } }) writer = csv.writer(f) writer.writerow([ 'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors' ]) print 'writing bad snls to file ...' for mpsnl_dict in mpsnl_cursor: mpsnl = MPStructureNL.from_dict(mpsnl_dict) row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ] row += _get_snl_extra_info(mpsnl) writer.writerow(row) sg_num = mpsnl.snlgroup_key.split('--')[1] if (bad_snls[mpsnl.snl_id] == 'SG default' and sg_num != '-1') or \ bad_snls[mpsnl.snl_id] == 'SG change': mpsnl.structure.remove_oxidation_states() sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1) badsnls_trace['x'].append(mpsnl.sg_num) badsnls_trace['y'].append(sf.get_spacegroup_number()) badsnls_trace['text'].append(mpsnl.snl_id) if bad_snls[mpsnl.snl_id] == 'SG default': print sg_num, sf.get_spacegroup_number() print 'plotting out-fig ...' out_fig['data'] = Data([bisectrix, badsnls_trace]) out_fig['layout'] = Layout( showlegend=False, hovermode='closest', title='Spacegroup Assignment Changes', xaxis=XAxis(showgrid=False, title='old SG number', range=[0, 230]), yaxis=YAxis(showgrid=False, title='new SG number', range=[0, 230]), ) filename = 'spacegroup_changes_' filename += datetime.datetime.now().strftime('%Y-%m-%d') py.plot(out_fig, filename=filename, auto_open=False) elif args.fig_id == 43: # SNLGroupMemberChecker matcher2 = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, comparator=ElementComparator()) print 'pulling data from plotly ...' trace = Scatter(x=[], y=[], text=[], mode='markers', name='mismatches') bad_snls = OrderedDict() # snlgroup_id : [ mismatching snl_ids ] for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']): if category != 'mismatch': continue for entry in text.split('<br>'): fields = entry.split(':') snlgroup_id = int(fields[0].split(',')[0]) print snlgroup_id snlgrp_dict = sma.snlgroups.find_one( {'snlgroup_id': snlgroup_id}) snlgrp = SNLGroup.from_dict(snlgrp_dict) s1 = snlgrp.canonical_structure.get_primitive_structure() bad_snls[snlgroup_id] = [] for i, snl_id in enumerate(fields[1].split(',')): mpsnl_dict = sma.snl.find_one({'snl_id': int(snl_id)}) if 'CederDahn Challenge' in mpsnl_dict['about'][ 'projects']: print 'skip CederDahn: %s' % snl_id continue mpsnl = MPStructureNL.from_dict(mpsnl_dict) s2 = mpsnl.structure.get_primitive_structure() is_match = matcher2.fit(s1, s2) if is_match: continue bad_snls[snlgroup_id].append(snl_id) trace['x'].append(snlgroup_id) trace['y'].append(i + 1) trace['text'].append(snl_id) if len(bad_snls[snlgroup_id]) < 1: bad_snls.pop(snlgroup_id, None) with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f: print 'pulling bad snlgroups from database ...' snlgroup_cursor = sma.snlgroups.find({ 'snlgroup_id': { '$in': bad_snls.keys() }, }) writer = csv.writer(f) writer.writerow( ['snlgroup_id', 'snlgroup_key', 'mismatching snl_ids']) print 'writing bad snlgroups to file ...' for snlgroup_dict in snlgroup_cursor: snlgroup = SNLGroup.from_dict(snlgroup_dict) row = [ snlgroup.snlgroup_id, snlgroup.canonical_snl.snlgroup_key, ' '.join(bad_snls[snlgroup.snlgroup_id]) ] writer.writerow(row) print 'plotting out-fig ...' out_fig = Figure() out_fig['data'] = Data([trace]) out_fig['layout'] = Layout( showlegend=False, hovermode='closest', title='Member Mismatches of SNLGroup Canonicals', xaxis=XAxis(showgrid=False, title='snlgroup_id', showexponent='none'), yaxis=YAxis(showgrid=False, title='# mismatching SNLs'), ) filename = 'groupmember_mismatches_' filename += datetime.datetime.now().strftime('%Y-%m-%d') py.plot(out_fig, filename=filename, auto_open=False) else: errors = Counter() bad_snls = OrderedDict() bad_snlgroups = OrderedDict() for i, d in enumerate(fig['data']): if not isinstance(d, Scatter): continue if not 'x' in d or not 'y' in d or not 'text' in d: continue start_id = int(d['name'].split(' - ')[0][:-1]) * 1000 marker_colors = d['marker']['color'] if i < 2 * num_snl_streams: # spacegroups errors += Counter(marker_colors) for idx, color in enumerate(marker_colors): snl_id = start_id + d['x'][idx] color_index = category_colors.index(color) category = categories[color_index] bad_snls[snl_id] = category else: # groupmembers for idx, color in enumerate(marker_colors): if color != category_colors[0]: continue snlgroup_id = start_id + d['x'][idx] mismatch_snl_id, canonical_snl_id = d['text'][idx].split( ' != ') bad_snlgroups[snlgroup_id] = int(mismatch_snl_id) print errors fig_data = fig['data'][-1] fig_data['x'] = [ errors[color] for color in fig_data['marker']['color'] ] filename = _get_filename() print filename #py.plot(fig, filename=filename) with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f: mpsnl_cursor = sma.snl.find({'snl_id': {'$in': bad_snls.keys()}}) writer = csv.writer(f) writer.writerow([ 'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors' ]) for mpsnl_dict in mpsnl_cursor: mpsnl = MPStructureNL.from_dict(mpsnl_dict) row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ] row += _get_snl_extra_info(mpsnl) writer.writerow(row) with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f: snlgrp_cursor = sma.snlgroups.find( {'snlgroup_id': { '$in': bad_snlgroups.keys() }}) first_mismatch_snls_cursor = sma.snl.find( {'snl_id': { '$in': bad_snlgroups.values() }}) first_mismatch_snl_info = OrderedDict() for mpsnl_dict in first_mismatch_snls_cursor: mpsnl = MPStructureNL.from_dict(mpsnl_dict) first_mismatch_snl_info[mpsnl.snl_id] = _get_snl_extra_info( mpsnl) writer = csv.writer(f) writer.writerow([ 'snlgroup_id', 'snlgroup_key', 'canonical_snl_id', 'first_mismatching_snl_id', 'nsites', 'remarks', 'projects', 'authors' ]) for snlgrp_dict in snlgrp_cursor: snlgrp = SNLGroup.from_dict(snlgrp_dict) first_mismatch_snl_id = bad_snlgroups[snlgrp.snlgroup_id] row = [ snlgrp.snlgroup_id, snlgrp.canonical_snl.snlgroup_key, snlgrp.canonical_snl.snl_id, first_mismatch_snl_id ] row += [ ' & '.join(pair) if pair[0] != pair[1] else pair[0] for pair in zip( _get_snl_extra_info(snlgrp.canonical_snl), first_mismatch_snl_info[int(first_mismatch_snl_id)]) ] writer.writerow(row)
def get_sg_info(ss): finder = SpacegroupAnalyzer(Structure.from_sites(ss), self.symm_prec) sgnum = finder.get_spacegroup_number() return sgnum
exit(1) # read structure if os.path.exists(fstruct): struct = mg.Structure.from_file(fstruct) else: print("File %s does not exist" % fstruct) exit(1) # symmetry information struct_sym = SpacegroupAnalyzer(struct) print("\nLattice details:") print("----------------") print("lattice type : {0}".format(struct_sym.get_lattice_type())) print("space group : {0} ({1})".format(struct_sym.get_spacegroup_symbol(), struct_sym.get_spacegroup_number())) # Compute first brillouin zone ibz = HighSymmKpath(struct) print("ibz type : {0}".format(ibz.name)) ibz.get_kpath_plot(savefig="path.png") # print specific kpoints in the first brillouin zone print("\nList of high symmetry k-points:") print("-------------------------------") for key, val in ibz.kpath["kpoints"].items(): print("%8s %s" % (key, str(val))) # suggested path for the band structure print("\nSuggested paths in first brillouin zone:") print("----------------------------------------")
def get_sg(s): finder = SpacegroupAnalyzer(s, symprec=self.symprec) return finder.get_spacegroup_number()
def __init__(self, struct, symprec=None): format_str = "{:.8f}" block = OrderedDict() loops = [] latt = struct.lattice comp = struct.composition no_oxi_comp = comp.element_composition spacegroup = ("P 1", 1) if symprec is not None: sf = SpacegroupAnalyzer(struct, symprec) spacegroup = (sf.get_spacegroup_symbol(), sf.get_spacegroup_number()) block["_symmetry_space_group_name_H-M"] = spacegroup[0] for cell_attr in ['a', 'b', 'c']: block["_cell_length_" + cell_attr] = format_str.format( getattr(latt, cell_attr)) for cell_attr in ['alpha', 'beta', 'gamma']: block["_cell_angle_" + cell_attr] = format_str.format( getattr(latt, cell_attr)) block["_symmetry_Int_Tables_number"] = spacegroup[1] block["_chemical_formula_structural"] = no_oxi_comp.reduced_formula block["_chemical_formula_sum"] = no_oxi_comp.formula block["_cell_volume"] = latt.volume.__str__() reduced_comp, fu = no_oxi_comp.get_reduced_composition_and_factor() block["_cell_formula_units_Z"] = str(int(fu)) if symprec is None: block["_symmetry_equiv_pos_site_id"] = ["1"] block["_symmetry_equiv_pos_as_xyz"] = ["x, y, z"] else: sf = SpacegroupAnalyzer(struct, symprec) def round_symm_trans(i): for t in TRANSLATIONS.values(): if abs(i - t) < symprec: return t if abs(i - round(i)) < symprec: return 0 raise ValueError("Invalid translation!") symmops = [] for op in sf.get_symmetry_operations(): v = op.translation_vector v = [round_symm_trans(i) for i in v] symmops.append(SymmOp.from_rotation_and_translation( op.rotation_matrix, v)) ops = [op.as_xyz_string() for op in symmops] block["_symmetry_equiv_pos_site_id"] = \ ["%d" % i for i in range(1, len(ops) + 1)] block["_symmetry_equiv_pos_as_xyz"] = ops loops.append(["_symmetry_equiv_pos_site_id", "_symmetry_equiv_pos_as_xyz"]) contains_oxidation = True try: symbol_to_oxinum = OrderedDict([ (el.__str__(), float(el.oxi_state)) for el in sorted(comp.elements)]) except AttributeError: symbol_to_oxinum = OrderedDict([(el.symbol, 0) for el in sorted(comp.elements)]) contains_oxidation = False if contains_oxidation: block["_atom_type_symbol"] = symbol_to_oxinum.keys() block["_atom_type_oxidation_number"] = symbol_to_oxinum.values() loops.append(["_atom_type_symbol", "_atom_type_oxidation_number"]) atom_site_type_symbol = [] atom_site_symmetry_multiplicity = [] atom_site_fract_x = [] atom_site_fract_y = [] atom_site_fract_z = [] atom_site_label = [] atom_site_occupancy = [] count = 1 if symprec is None: for site in struct: for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(sp.__str__()) atom_site_symmetry_multiplicity.append("1") atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(occu.__str__()) count += 1 else: # The following just presents a deterministic ordering. unique_sites = [ (sorted(sites, key=lambda s: tuple([abs(x) for x in s.frac_coords]))[0], len(sites)) for sites in sf.get_symmetrized_structure().equivalent_sites ] for site, mult in sorted( unique_sites, key=lambda t: (t[0].species_and_occu.average_electroneg, -t[1], t[0].a, t[0].b, t[0].c)): for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(sp.__str__()) atom_site_symmetry_multiplicity.append("%d" % mult) atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(occu.__str__()) count += 1 block["_atom_site_type_symbol"] = atom_site_type_symbol block["_atom_site_label"] = atom_site_label block["_atom_site_symmetry_multiplicity"] = \ atom_site_symmetry_multiplicity block["_atom_site_fract_x"] = atom_site_fract_x block["_atom_site_fract_y"] = atom_site_fract_y block["_atom_site_fract_z"] = atom_site_fract_z block["_atom_site_occupancy"] = atom_site_occupancy loops.append(["_atom_site_type_symbol", "_atom_site_label", "_atom_site_symmetry_multiplicity", "_atom_site_fract_x", "_atom_site_fract_y", "_atom_site_fract_z", "_atom_site_occupancy"]) d = OrderedDict() d[comp.reduced_formula] = CifBlock(block, loops, comp.reduced_formula) self._cf = CifFile(d)
class SpacegroupAnalyzerTest(PymatgenTest): def setUp(self): p = Poscar.from_file(os.path.join(test_dir, 'POSCAR')) self.structure = p.structure self.sg = SpacegroupAnalyzer(self.structure, 0.001) self.disordered_structure = self.get_structure('Li10GeP2S12') self.disordered_sg = SpacegroupAnalyzer(self.disordered_structure, 0.001) s = p.structure.copy() site = s[0] del s[0] s.append(site.species_and_occu, site.frac_coords) self.sg3 = SpacegroupAnalyzer(s, 0.001) graphite = self.get_structure('Graphite') graphite.add_site_property("magmom", [0.1] * len(graphite)) self.sg4 = SpacegroupAnalyzer(graphite, 0.001) def test_get_space_symbol(self): self.assertEqual(self.sg.get_spacegroup_symbol(), "Pnma") self.assertEqual(self.disordered_sg.get_spacegroup_symbol(), "P4_2/nmc") self.assertEqual(self.sg3.get_spacegroup_symbol(), "Pnma") self.assertEqual(self.sg4.get_spacegroup_symbol(), "R-3m") def test_get_space_number(self): self.assertEqual(self.sg.get_spacegroup_number(), 62) self.assertEqual(self.disordered_sg.get_spacegroup_number(), 137) self.assertEqual(self.sg4.get_spacegroup_number(), 166) def test_get_hall(self): self.assertEqual(self.sg.get_hall(), '-P 2ac 2n') self.assertEqual(self.disordered_sg.get_hall(), 'P 4n 2n -1n') def test_get_pointgroup(self): self.assertEqual(self.sg.get_point_group(), 'mmm') self.assertEqual(self.disordered_sg.get_point_group(), '4/mmm') def test_get_symmetry_dataset(self): ds = self.sg.get_symmetry_dataset() self.assertEqual(ds['international'], 'Pnma') def test_get_crystal_system(self): crystal_system = self.sg.get_crystal_system() self.assertEqual('orthorhombic', crystal_system) self.assertEqual('tetragonal', self.disordered_sg.get_crystal_system()) def test_get_symmetry_operations(self): fracsymmops = self.sg.get_symmetry_operations() symmops = self.sg.get_symmetry_operations(True) self.assertEqual(len(symmops), 8) latt = self.structure.lattice for fop, op in zip(fracsymmops, symmops): for site in self.structure: newfrac = fop.operate(site.frac_coords) newcart = op.operate(site.coords) self.assertTrue(np.allclose(latt.get_fractional_coords(newcart), newfrac)) found = False newsite = PeriodicSite(site.species_and_occu, newcart, latt, coords_are_cartesian=True) for testsite in self.structure: if newsite.is_periodic_image(testsite, 1e-3): found = True break self.assertTrue(found) def test_get_refined_structure(self): for a in self.sg.get_refined_structure().lattice.angles: self.assertEqual(a, 90) refined = self.disordered_sg.get_refined_structure() for a in refined.lattice.angles: self.assertEqual(a, 90) self.assertEqual(refined.lattice.a, refined.lattice.b) s = self.get_structure('Li2O') sg = SpacegroupAnalyzer(s, 0.001) self.assertEqual(sg.get_refined_structure().num_sites, 4 * s.num_sites) def test_get_symmetrized_structure(self): symm_struct = self.sg.get_symmetrized_structure() for a in symm_struct.lattice.angles: self.assertEqual(a, 90) self.assertEqual(len(symm_struct.equivalent_sites), 5) symm_struct = self.disordered_sg.get_symmetrized_structure() self.assertEqual(len(symm_struct.equivalent_sites), 8) self.assertEqual([len(i) for i in symm_struct.equivalent_sites], [16,4,8,4,2,8,8,8]) s1 = symm_struct.equivalent_sites[1][1] s2 = symm_struct[symm_struct.equivalent_indices[1][1]] self.assertEqual(s1, s2) self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1) def test_find_primitive(self): """ F m -3 m Li2O testing of converting to primitive cell """ parser = CifParser(os.path.join(test_dir, 'Li2O.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure) primitive_structure = s.find_primitive() self.assertEqual(primitive_structure.formula, "Li2 O1") # This isn't what is expected. All the angles should be 60 self.assertAlmostEqual(primitive_structure.lattice.alpha, 60) self.assertAlmostEqual(primitive_structure.lattice.beta, 60) self.assertAlmostEqual(primitive_structure.lattice.gamma, 60) self.assertAlmostEqual(primitive_structure.lattice.volume, structure.lattice.volume / 4.0) def test_get_ir_reciprocal_mesh(self): grid=self.sg.get_ir_reciprocal_mesh() self.assertEqual(len(grid), 216) self.assertAlmostEquals(grid[1][0][0], 0.1) self.assertAlmostEquals(grid[1][0][1], 0.0) self.assertAlmostEquals(grid[1][0][2], 0.0) self.assertEqual(grid[1][1], 2) def test_get_conventional_standard_structure(self): parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461) self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461) self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461) parser = CifParser(os.path.join(test_dir, 'btet_1915.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235) self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235) self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687) parser = CifParser(os.path.join(test_dir, 'orci_1010.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999) self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296) self.assertAlmostEqual(conv.lattice.c, 5.373703587040775) parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998) self.assertAlmostEqual(conv.lattice.b, 31.437979757624728) self.assertAlmostEqual(conv.lattice.c, 3.99648651) parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903) self.assertAlmostEqual(conv.lattice.gamma, 90) self.assertAlmostEqual(conv.lattice.a, 14.033435583000625) self.assertAlmostEqual(conv.lattice.b, 3.96052850731) self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002) parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 90) self.assertAlmostEqual(conv.lattice.beta, 90) self.assertAlmostEqual(conv.lattice.gamma, 120) self.assertAlmostEqual(conv.lattice.a, 3.699919902005897) self.assertAlmostEqual(conv.lattice.b, 3.699919902005897) self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003) def test_get_primitive_standard_structure(self): parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001) self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001) self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001) self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145) parser = CifParser(os.path.join(test_dir, 'btet_1915.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 105.015053349) self.assertAlmostEqual(prim.lattice.beta, 105.015053349) self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999) self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791) parser = CifParser(os.path.join(test_dir, 'orci_1010.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001) self.assertAlmostEqual(prim.lattice.beta, 105.856239333) self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001) self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852) parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 164.985257335) self.assertAlmostEqual(prim.lattice.a, 15.854897098324196) self.assertAlmostEqual(prim.lattice.b, 15.854897098324196) self.assertAlmostEqual(prim.lattice.c, 3.99648651) parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999) self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779) self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569) self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002) parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 120) self.assertAlmostEqual(prim.lattice.a, 3.699919902005897) self.assertAlmostEqual(prim.lattice.b, 3.699919902005897) self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003)
def _gen_input_file(self): """ Generate the necessary struct_enum.in file for enumlib. See enumlib documentation for details. """ coord_format = "{:.6f} {:.6f} {:.6f}" # Using symmetry finder, get the symmetrically distinct sites. fitter = SpacegroupAnalyzer(self.structure, self.symm_prec) symmetrized_structure = fitter.get_symmetrized_structure() logger.debug("Spacegroup {} ({}) with {} distinct sites".format( fitter.get_spacegroup_symbol(), fitter.get_spacegroup_number(), len(symmetrized_structure.equivalent_sites))) """ Enumlib doesn"t work when the number of species get too large. To simplify matters, we generate the input file only with disordered sites and exclude the ordered sites from the enumeration. The fact that different disordered sites with the exact same species may belong to different equivalent sites is dealt with by having determined the spacegroup earlier and labelling the species differently. """ # index_species and index_amounts store mappings between the indices # used in the enum input file, and the actual species and amounts. index_species = [] index_amounts = [] #Stores the ordered sites, which are not enumerated. ordered_sites = [] disordered_sites = [] coord_str = [] for sites in symmetrized_structure.equivalent_sites: if sites[0].is_ordered: ordered_sites.append(sites) else: sp_label = [] species = {k: v for k, v in sites[0].species_and_occu.items()} if sum(species.values()) < 1 - EnumlibAdaptor.amount_tol: #Let us first make add a dummy element for every single #site whose total occupancies don't sum to 1. species[DummySpecie("X")] = 1 - sum(species.values()) for sp in species.keys(): if sp not in index_species: index_species.append(sp) sp_label.append(len(index_species) - 1) index_amounts.append(species[sp] * len(sites)) else: ind = index_species.index(sp) sp_label.append(ind) index_amounts[ind] += species[sp] * len(sites) sp_label = "/".join(["{}".format(i) for i in sorted(sp_label)]) for site in sites: coord_str.append("{} {}".format( coord_format.format(*site.coords), sp_label)) disordered_sites.append(sites) def get_sg_info(ss): finder = SpacegroupAnalyzer(Structure.from_sites(ss), self.symm_prec) sgnum = finder.get_spacegroup_number() return sgnum curr_sites = list(itertools.chain.from_iterable(disordered_sites)) min_sgnum = get_sg_info(curr_sites) logger.debug("Disorderd sites has sgnum %d" % (min_sgnum)) #It could be that some of the ordered sites has a lower symmetry than #the disordered sites. So we consider the lowest symmetry sites as #disordered in our enumeration. self.ordered_sites = [] to_add = [] if self.check_ordered_symmetry: for sites in ordered_sites: temp_sites = list(curr_sites) + sites sgnum = get_sg_info(temp_sites) if sgnum < min_sgnum: logger.debug("Adding {} to sites to be ordered. " "New sgnum {}".format(sites, sgnum)) to_add = sites min_sgnum = sgnum for sites in ordered_sites: if sites == to_add: index_species.append(sites[0].specie) index_amounts.append(len(sites)) sp_label = len(index_species) - 1 logger.debug( "Lowest symmetry {} sites are included in enum.".format( sites[0].specie)) for site in sites: coord_str.append("{} {}".format( coord_format.format(*site.coords), sp_label)) disordered_sites.append(sites) else: self.ordered_sites.extend(sites) self.index_species = index_species lattice = self.structure.lattice output = [self.structure.formula, "bulk"] for vec in lattice.matrix: output.append(coord_format.format(*vec)) output.append("{}".format(len(index_species))) output.append("{}".format(len(coord_str))) output.extend(coord_str) output.append("{} {}".format(self.min_cell_size, self.max_cell_size)) output.append(str(self.enum_precision_parameter)) output.append("partial") ndisordered = sum([len(s) for s in disordered_sites]) base = ndisordered #10 ** int(math.ceil(math.log10(ndisordered))) #To get a reasonable number of structures, we fix concentrations to the #range expected in the original structure. total_amounts = sum(index_amounts) for amt in index_amounts: conc = amt / total_amounts if abs(conc * base - round(conc * base)) < 1e-5: output.append("{} {} {}".format(int(round(conc * base)), int(round(conc * base)), base)) else: min_conc = int(math.floor(conc * base)) output.append("{} {} {}".format(min_conc - 1, min_conc + 1, base)) output.append("") logger.debug("Generated input file:\n{}".format("\n".join(output))) with open("struct_enum.in", "w") as f: f.write("\n".join(output))
def generate_doc(self, dir_name, vasprun_files): """ Process aflow style runs, where each run is actually a combination of two vasp runs. """ try: fullpath = os.path.abspath(dir_name) #Defensively copy the additional fields first. This is a MUST. #Otherwise, parallel updates will see the same object and inserts #will be overridden!! d = {k: v for k, v in self.additional_fields.items()} d["dir_name"] = fullpath d["schema_version"] = VaspToDbTaskDrone.__version__ d["calculations"] = [ self.process_vasprun(dir_name, taskname, filename) for taskname, filename in vasprun_files.items()] d1 = d["calculations"][0] d2 = d["calculations"][-1] #Now map some useful info to the root level. for root_key in ["completed_at", "nsites", "unit_cell_formula", "reduced_cell_formula", "pretty_formula", "elements", "nelements", "cif", "density", "is_hubbard", "hubbards", "run_type"]: d[root_key] = d2[root_key] d["chemsys"] = "-".join(sorted(d2["elements"])) #store any overrides to the exchange correlation functional xc = d2["input"]["incar"].get("GGA") if xc: xc = xc.upper() d["input"] = {"crystal": d1["input"]["crystal"], "is_lasph": d2["input"]["incar"].get("LASPH", False), "potcar_spec": d1["input"].get("potcar_spec"), "xc_override": xc} vals = sorted(d2["reduced_cell_formula"].values()) d["anonymous_formula"] = {string.ascii_uppercase[i]: float(vals[i]) for i in range(len(vals))} d["output"] = { "crystal": d2["output"]["crystal"], "final_energy": d2["output"]["final_energy"], "final_energy_per_atom": d2["output"]["final_energy_per_atom"]} d["name"] = "aflow" p = d2["input"]["potcar_type"][0].split("_") pot_type = p[0] functional = "lda" if len(pot_type) == 1 else "_".join(p[1:]) d["pseudo_potential"] = {"functional": functional.lower(), "pot_type": pot_type.lower(), "labels": d2["input"]["potcar"]} if len(d["calculations"]) == len(self.runs) or \ list(vasprun_files.keys())[0] != "relax1": d["state"] = "successful" if d2["has_vasp_completed"] \ else "unsuccessful" else: d["state"] = "stopped" d["analysis"] = get_basic_analysis_and_error_checks(d) sg = SpacegroupAnalyzer(Structure.from_dict(d["output"]["crystal"]), 0.1) d["spacegroup"] = {"symbol": sg.get_spacegroup_symbol(), "number": sg.get_spacegroup_number(), "point_group": sg.get_point_group(), "source": "spglib", "crystal_system": sg.get_crystal_system(), "hall": sg.get_hall()} d["last_updated"] = datetime.datetime.today() return d except Exception as ex: import traceback print(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) return None