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_space_group_operations() sgnum = sf.get_space_group_number() if sf.get_space_group_number() \ else -1 sgsym = sf.get_space_group_symbol() if sf.get_space_group_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_symbol() 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) 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 set_space_group_from_structure(self, structure): spga = SpacegroupAnalyzer(structure=structure) self.crystal_system = spga.get_crystal_system() self.hall = spga.get_hall() self.number = spga.get_space_group_number() self.source = "spglib" self.symbol = spga.get_space_group_symbol()
def set_material_data_from_structure(self, structure, space_group=True, symprec=1e-3, angle_tolerance=5): comp = structure.composition el_amt = structure.composition.get_el_amt_dict() self.unit_cell_formula = comp.as_dict() self.reduced_cell_formula = comp.to_reduced_dict self.elements = list(el_amt.keys()) self.nelements = len(el_amt) self.pretty_formula = comp.reduced_formula self.anonymous_formula = comp.anonymized_formula self.nsites = comp.num_atoms self.chemsys = "-".join(sorted(el_amt.keys())) if space_group: sym = SpacegroupAnalyzer(structure, symprec=symprec, angle_tolerance=angle_tolerance) self.spacegroup = SpaceGroupDocument( crystal_system=sym.get_crystal_system(), hall=sym.get_hall(), number=sym.get_space_group_number(), point_group=sym.get_point_group_symbol(), symbol=sym.get_space_group_symbol(), source="spglib")
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_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "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 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 from_structure(cls, structure: Structure) -> "SymmetryData": symprec = SETTINGS.SYMPREC sg = SpacegroupAnalyzer(structure, symprec=symprec) symmetry: Dict[str, Any] = {"symprec": symprec} if not sg.get_symmetry_dataset(): sg = SpacegroupAnalyzer(structure, 1e-3, 1) symmetry["symprec"] = 1e-3 symmetry.update({ "source": "spglib", "symbol": sg.get_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "crystal_system": CrystalSystem(sg.get_crystal_system().title()), "hall": sg.get_hall(), "version": spglib.__version__, }) return SymmetryData(**symmetry)
def run_task(self, fw_spec): additional_fields = self.get("additional_fields", {}) # pass the additional_fields first to avoid overriding BoltztrapAnalyzer items d = additional_fields.copy() btrap_dir = os.path.join(os.getcwd(), "boltztrap") d["boltztrap_dir"] = btrap_dir bta = BoltztrapAnalyzer.from_files(btrap_dir) d.update(bta.as_dict()) d["scissor"] = bta.intrans["scissor"] # 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"] bandstructure_dir = os.getcwd() d["bandstructure_dir"] = bandstructure_dir # add the structure v, o = get_vasprun_outcar(bandstructure_dir, parse_eigen=False, parse_dos=False) structure = v.final_structure d["structure"] = structure.as_dict() d["formula_pretty"] = structure.composition.reduced_formula d.update(get_meta_from_structure(structure)) # add the spacegroup sg = SpacegroupAnalyzer(Structure.from_dict(d["structure"]), 0.1) d["spacegroup"] = {"symbol": sg.get_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "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: del d["dos"] with open(os.path.join(btrap_dir, "boltztrap.json"), "w") as f: f.write(json.dumps(d, default=DATETIME_HANDLER)) else: mmdb = VaspCalcDb.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 add_cifs(doc): struc = Structure.from_dict(doc["structure"]) sym_finder = SpacegroupAnalyzer(struc, symprec=0.1) doc["cif"] = str(CifWriter(struc)) doc["cifs"] = {} if sym_finder.get_hall(): primitive = sym_finder.get_primitive_standard_structure() conventional = sym_finder.get_conventional_standard_structure() refined = sym_finder.get_refined_structure() doc["cifs"]["primitive"] = str(CifWriter(primitive)) doc["cifs"]["refined"] = str(CifWriter(refined)) doc["cifs"]["conventional_standard"] = str(CifWriter(conventional)) doc["cifs"]["computed"] = str(CifWriter(struc)) doc["spacegroup"]["symbol"] = sym_finder.get_space_group_symbol() doc["spacegroup"]["number"] = sym_finder.get_space_group_number() doc["spacegroup"]["point_group"] = sym_finder.get_point_group_symbol() doc["spacegroup"]["crystal_system"] = sym_finder.get_crystal_system() doc["spacegroup"]["hall"] = sym_finder.get_hall() else: doc["cifs"]["primitive"] = None doc["cifs"]["refined"] = None doc["cifs"]["conventional_standard"] = None
def analyze_symmetry(request): results = {} symprec = float(request.POST["symprec"]) angle_tolerance = float(request.POST["angle_tolerance"]) for name, f in request.FILES.items(): name, s = get_structure(f) a = SpacegroupAnalyzer(s, symprec=symprec, angle_tolerance=angle_tolerance) d = {} d["international"] = a.get_space_group_symbol() d["number"] = a.get_space_group_number() d["hall"] = a.get_hall() d["point_group"] = a.get_point_group() d["crystal_system"] = a.get_crystal_system() results[name] = d return results
def structure_symmetry(): structs, fnames = read_structures() multi_structs(structs, fnames) for struct, fname in zip(structs, fnames): if isinstance(struct, Structure): sa = SpacegroupAnalyzer(struct) print("file name: {}".format(fname)) print("{} : {}".format('Structure Type', 'periodicity')) print("{} : {}".format('Lattice Type', sa.get_lattice_type())) print("{} : {}".format('Space Group ID', sa.get_space_group_number())) print("{} : {}".format('International Symbol', sa.get_space_group_symbol())) print("{} : {}".format('Hall Symbol', sa.get_hall())) sepline() if isinstance(struct, Molecule): print("file name: {}".format(fname)) sa = PointGroupAnalyzer(struct) print("{} : {}".format('Structure Type', 'non-periodicity')) print("{} : {}".format('International Symbol', ast.get_pointgroup())) return True
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_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "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 set_material_data_from_structure(self, structure, space_group=True, symprec=1e-3, angle_tolerance=5): """ Sets the fields of the Document using a Structure and Spglib to determine the space group properties Args: structure: A |Structure| space_group: if True sets the spacegroup fields using spglib_. symprec (float): Tolerance for symmetry finding. angle_tolerance (float): Angle tolerance for symmetry finding. """ comp = structure.composition el_amt = structure.composition.get_el_amt_dict() self.unit_cell_formula = comp.as_dict() self.reduced_cell_formula = comp.to_reduced_dict self.elements = list(el_amt.keys()) self.nelements = len(el_amt) self.pretty_formula = comp.reduced_formula self.anonymous_formula = comp.anonymized_formula self.nsites = comp.num_atoms self.chemsys = "-".join(sorted(el_amt.keys())) self.full_formula = comp.formula if space_group: sym = SpacegroupAnalyzer(structure, symprec=symprec, angle_tolerance=angle_tolerance) self.spacegroup = SpaceGroupDocument( crystal_system=sym.get_crystal_system(), hall=sym.get_hall(), number=sym.get_space_group_number(), point_group=sym.get_point_group_symbol(), symbol=sym.get_space_group_symbol(), source="spglib")
def generate_doc(self, dir_name, vasprun_files, outcar_files): """ Adapted from matgendb.creator.generate_doc """ try: # basic properties, incl. calcs_reversed and run_stats fullpath = os.path.abspath(dir_name) d = {k: v for k, v in self.additional_fields.items()} d["schema"] = {"code": "atomate", "version": VaspDrone.__version__} d["dir_name"] = fullpath d["calcs_reversed"] = [self.process_vasprun(dir_name, taskname, filename) for taskname, filename in vasprun_files.items()] outcar_data = [Outcar(os.path.join(dir_name, filename)).as_dict() for taskname, filename in outcar_files.items()] run_stats = {} for i, d_calc in enumerate(d["calcs_reversed"]): run_stats[d_calc["task"]["name"]] = outcar_data[i].pop("run_stats") if d_calc.get("output"): d_calc["output"].update({"outcar": outcar_data[i]}) else: d_calc["output"] = {"outcar": outcar_data[i]} try: overall_run_stats = {} for key in ["Total CPU time used (sec)", "User time (sec)", "System time (sec)", "Elapsed time (sec)"]: overall_run_stats[key] = sum([v[key] for v in run_stats.values()]) run_stats["overall"] = overall_run_stats except: logger.error("Bad run stats for {}.".format(fullpath)) d["run_stats"] = run_stats # reverse the calculations data order so newest calc is first d["calcs_reversed"].reverse() # set root formula/composition keys based on initial and final calcs d_calc_init = d["calcs_reversed"][-1] d_calc_final = d["calcs_reversed"][0] d["chemsys"] = "-".join(sorted(d_calc_final["elements"])) comp = Composition(d_calc_final["composition_unit_cell"]) d["formula_anonymous"] = comp.anonymized_formula d["formula_reduced_abc"] = comp.reduced_composition.alphabetical_formula for root_key in ["completed_at", "nsites", "composition_unit_cell", "composition_reduced", "formula_pretty", "elements", "nelements"]: d[root_key] = d_calc_final[root_key] # store the input key based on initial calc # store any overrides to the exchange correlation functional xc = d_calc_init["input"]["incar"].get("GGA") if xc: xc = xc.upper() p = d_calc_init["input"]["potcar_type"][0].split("_") pot_type = p[0] functional = "lda" if len(pot_type) == 1 else "_".join(p[1:]) d["input"] = {"structure": d_calc_init["input"]["structure"], "is_hubbard": d_calc_init.pop("is_hubbard"), "hubbards": d_calc_init.pop("hubbards"), "is_lasph": d_calc_init["input"]["incar"].get("LASPH", False), "potcar_spec": d_calc_init["input"].get("potcar_spec"), "xc_override": xc, "pseudo_potential": {"functional": functional.lower(), "pot_type": pot_type.lower(), "labels": d_calc_init["input"]["potcar"]}, "parameters": d_calc_init["input"]["parameters"], "incar": d_calc_init["input"]["incar"] } # store the output key based on final calc d["output"] = { "structure": d_calc_final["output"]["structure"], "density": d_calc_final.pop("density"), "energy": d_calc_final["output"]["energy"], "energy_per_atom": d_calc_final["output"]["energy_per_atom"], "forces": d_calc_final["output"]["ionic_steps"][-1].get("forces"), "stress": d_calc_final["output"]["ionic_steps"][-1].get("stress")} # patch calculated magnetic moments into final structure if len(d_calc_final["output"]["outcar"]["magnetization"]) != 0: magmoms = [m["tot"] for m in d_calc_final["output"]["outcar"]["magnetization"]] s = Structure.from_dict(d["output"]["structure"]) s.add_site_property('magmom', magmoms) d["output"]["structure"] = s.as_dict() calc = d["calcs_reversed"][0] try: d["output"].update({"bandgap": calc["output"]["bandgap"], "cbm": calc["output"]["cbm"], "vbm": calc["output"]["vbm"], "is_gap_direct": calc["output"]["is_gap_direct"], "is_metal": calc["output"]["is_metal"]}) if not calc["output"]["is_gap_direct"]: d["output"]["direct_gap"] = calc["output"]["direct_gap"] if "transition" in calc["output"]: d["output"]["transition"] = calc["output"]["transition"] except Exception: if self.bandstructure_mode is True: import traceback logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise sg = SpacegroupAnalyzer(Structure.from_dict(d_calc_final["output"]["structure"]), 0.1) if not sg.get_symmetry_dataset(): sg = SpacegroupAnalyzer(Structure.from_dict(d_calc_final["output"]["structure"]), 1e-3, 1) d["output"]["spacegroup"] = { "source": "spglib", "symbol": sg.get_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "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_final["output"][k] if SymmOp.inversion() not in sg.get_symmetry_operations(): for k in ["piezo_ionic_tensor", "piezo_tensor"]: d["output"][k] = d_calc_final["output"]["outcar"][k] d["state"] = "successful" if d_calc["has_vasp_completed"] else "unsuccessful" self.set_analysis(d) d["last_updated"] = datetime.datetime.today() return d except Exception: import traceback logger.error(traceback.format_exc()) logger.error("Error in " + os.path.abspath(dir_name) + ".\n" + traceback.format_exc()) raise
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_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "source": "spglib", "crystal_system": sg.get_crystal_system(), "hall": sg.get_hall() } d["oxide_type"] = d2["oxide_type"] 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 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_space_group_symbol(), "number": sg.get_space_group_number(), "point_group": sg.get_point_group_symbol(), "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 process_item(self, item): """ Finds all predicted structures for given item Args: item (dict): structure prediction request and relevant oxidation state-labeled structure templates Returns: (dict, dict): A tuple containing updated request doc and a list of crystal docs to update """ request = item["request"] templates = item["templates"] self.logger.info( f"Labeling oxidation states for {len(templates)} structure templates" ) oxi_labeled_templates = [] for template in templates: struct = Structure.from_dict(template["structure"]) try: oxi_labeled_templates.append({ "structure": self.auto_oxi.apply_transformation(struct), "id": template[self.structure_templates.key], }) except: continue # if auto-oxidation fails, try next structure self.logger.info( f"Successfully labeled oxidation states for {len(oxi_labeled_templates)} structures" ) self.logger.info("Substituting original species into structures") predicted_structs = Substitutor( threshold=request["threshold"]).pred_from_structures( request["original_species"], oxi_labeled_templates, remove_duplicates=True, remove_existing=True, ) predicted_structs.sort(key=lambda s: s.other_parameters["proba"], reverse=True) structure_prediction_id = request[self.requests.key] crystal_docs = [] summaries = [] self.logger.info( f"Found {len(predicted_structs)} predicted structures. Generating crystal docs (XRDs, CIFs, etc." ) for number_id, struct in enumerate(predicted_structs): crystal = {} summary = {} xrd_dict = {} final_structure = struct.final_structure sga = SpacegroupAnalyzer(final_structure, symprec=0.1) for rad_source in ["CuKa", "AgKa", "MoKa", "FeKa"]: xrdc = XRDCalculator(wavelength=rad_source) pattern = xrdc.get_pattern(final_structure, two_theta_range=None) xrd_dict[rad_source] = pattern transformed_structure = struct.to_snl( f"{request['name']} <{request['email']}>", remarks=["Created by MP Structure Predictor"], ) crystal[self.requests.key] = structure_prediction_id crystal[self.crystals.key] = number_id crystal["probability"] = struct.other_parameters["proba"] crystal["transformed_structure"] = transformed_structure crystal["xrd"] = xrd_dict crystal["space_group_info"] = { "symbol": sga.get_space_group_symbol(), "number": sga.get_space_group_number(), "hall": sga.get_hall(), "crystal_system": sga.get_crystal_system(), } summary[self.crystals.key] = number_id summary["probability"] = struct.other_parameters["proba"] summary[ "pretty_formula"] = final_structure.composition.reduced_formula summary["nsites"] = len(final_structure) summary["space_group"] = sga.get_space_group_symbol() summary["cif"] = str(CifWriter(final_structure)) crystal_docs.append(jsanitize(crystal, strict=True)) summaries.append(jsanitize(summary, strict=True)) self.logger.info( f"Successfully generated {len(crystal_docs)} crystal docs for request {request['original_species']}" ) request.update({ "state": "COMPLETE", "completed_at": datetime.utcnow(), "num_crystals": len(crystal_docs), "crystals": summaries, }) return request, crystal_docs
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 set_material_data_from_structure(self, structure, space_group=True, symprec=1e-3, angle_tolerance=5): """ Sets the fields of the Document using a Structure and Spglib to determine the space group properties Args: structure: A |Structure| space_group: if True sets the spacegroup fields using spglib_. symprec (float): Tolerance for symmetry finding. angle_tolerance (float): Angle tolerance for symmetry finding. """ comp = structure.composition el_amt = structure.composition.get_el_amt_dict() self.unit_cell_formula = comp.as_dict() self.reduced_cell_formula = comp.to_reduced_dict self.elements = list(el_amt.keys()) self.nelements = len(el_amt) self.pretty_formula = comp.reduced_formula self.anonymous_formula = comp.anonymized_formula self.nsites = comp.num_atoms self.chemsys = "-".join(sorted(el_amt.keys())) if space_group: sym = SpacegroupAnalyzer(structure, symprec=symprec, angle_tolerance=angle_tolerance) self.spacegroup = SpaceGroupDocument(crystal_system=sym.get_crystal_system(), hall=sym.get_hall(), number=sym.get_space_group_number(), point_group=sym.get_point_group_symbol(), symbol=sym.get_space_group_symbol(), source="spglib")
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) self.structure4 = graphite def test_primitive(self): s = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]]) a = SpacegroupAnalyzer(s) self.assertEqual(len(s), 4) self.assertEqual(len(a.find_primitive()), 1) def test_is_laue(self): s = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]]) a = SpacegroupAnalyzer(s) self.assertTrue(a.is_laue()) def test_magnetic(self): lfp = PymatgenTest.get_structure("LiFePO4") sg = SpacegroupAnalyzer(lfp, 0.1) self.assertEqual(sg.get_space_group_symbol(), "Pnma") magmoms = [0] * len(lfp) magmoms[4] = 1 magmoms[5] = -1 magmoms[6] = 1 magmoms[7] = -1 lfp.add_site_property("magmom", magmoms) sg = SpacegroupAnalyzer(lfp, 0.1) self.assertEqual(sg.get_space_group_symbol(), "Pnma") def test_get_space_symbol(self): self.assertEqual(self.sg.get_space_group_symbol(), "Pnma") self.assertEqual(self.disordered_sg.get_space_group_symbol(), "P4_2/nmc") self.assertEqual(self.sg3.get_space_group_symbol(), "Pnma") self.assertEqual(self.sg4.get_space_group_symbol(), "P6_3/mmc") def test_get_space_number(self): self.assertEqual(self.sg.get_space_group_number(), 62) self.assertEqual(self.disordered_sg.get_space_group_number(), 137) self.assertEqual(self.sg4.get_space_group_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_symbol(), 'mmm') self.assertEqual(self.disordered_sg.get_point_group_symbol(), '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): for sg, structure in [(self.sg, self.structure), (self.sg4, self.structure4)]: pgops = sg.get_point_group_operations() fracsymmops = sg.get_symmetry_operations() symmops = sg.get_symmetry_operations(True) latt = structure.lattice for fop, op, pgop in zip(fracsymmops, symmops, pgops): # translation vector values should all be 0 or 0.5 t = fop.translation_vector * 2 self.assertArrayAlmostEqual(t - np.round(t), 0) self.assertArrayAlmostEqual(fop.rotation_matrix, pgop.rotation_matrix) for site in 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 structure: if newsite.is_periodic_image(testsite, 1e-3): found = True break self.assertTrue(found) # Make sure this works for any position, not just the atomic # ones. random_fcoord = np.random.uniform(size=(3)) random_ccoord = latt.get_cartesian_coords(random_fcoord) newfrac = fop.operate(random_fcoord) newcart = op.operate(random_ccoord) self.assertTrue(np.allclose(latt.get_fractional_coords(newcart), newfrac)) 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.01) 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) self.assertEqual(symm_struct.wyckoff_symbols[0], '16h') # self.assertEqual(symm_struct[0].wyckoff, "16h") 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.assertAlmostEqual(grid[1][0][0], 0.1) self.assertAlmostEqual(grid[1][0][1], 0.0) self.assertAlmostEqual(grid[1][0][2], 0.0) self.assertAlmostEqual(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, 'orac_632475.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, 3.1790663399999999) self.assertAlmostEqual(conv.lattice.b, 9.9032878699999998) self.assertAlmostEqual(conv.lattice.c, 3.5372412099999999) 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, 'orac_632475.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, 144.40557588533386) self.assertAlmostEqual(prim.lattice.a, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.b, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.c, 3.5372412099999999) 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)
def update_contents(data, symprec, angle_tolerance): if not data: return html.Div() struct = self.from_data(data) if not isinstance(struct, Structure): return html.Div( "Can only analyze symmetry of crystal structures at present." ) kwargs = self.reconstruct_kwargs_from_state( callback_context.inputs) symprec = kwargs["symprec"] angle_tolerance = kwargs["angle_tolerance"] if symprec <= 0: return html.Span( f"Please use a positive symmetry-finding tolerance (currently {symprec})." ) sga = SpacegroupAnalyzer(struct, symprec=symprec, angle_tolerance=angle_tolerance) try: data = dict() data["Crystal System"] = sga.get_crystal_system().title() data["Lattice System"] = sga.get_lattice_type().title() data["Hall Number"] = sga.get_hall() data["International Number"] = sga.get_space_group_number() data["Symbol"] = unicodeify_spacegroup( sga.get_space_group_symbol()) data["Point Group"] = unicodeify_spacegroup( sga.get_point_group_symbol()) sym_struct = sga.get_symmetrized_structure() except Exception: return html.Span( f"Failed to calculate symmetry with this combination of " f"symmetry-finding ({symprec}) and angle tolerances ({angle_tolerance})." ) datalist = get_data_list(data) wyckoff_contents = [] wyckoff_data = sorted( zip(sym_struct.wyckoff_symbols, sym_struct.equivalent_sites), key=lambda x: "".join(filter(lambda w: w.isalpha(), x[0])), ) for symbol, equiv_sites in wyckoff_data: wyckoff_contents.append( html.Label( f"{symbol}, {unicodeify_species(equiv_sites[0].species_string)}", className="mpc-label", )) site_data = [( self.pretty_frac_format(site.frac_coords[0]), self.pretty_frac_format(site.frac_coords[1]), self.pretty_frac_format(site.frac_coords[2]), ) for site in equiv_sites] wyckoff_contents.append(get_table(site_data)) return Columns([ Column([H5("Overview"), datalist]), Column([H5("Wyckoff Positions"), html.Div(wyckoff_contents)]), ])
def update_contents(self, new_store_contents, symprec, angle_tolerance): try: # input sanitation symprec = float(literal_eval(str(symprec))) angle_tolerance = float(literal_eval(str(angle_tolerance))) except: raise PreventUpdate struct_or_mol = self.from_data(new_store_contents) if not isinstance(struct_or_mol, Structure): return html.Div( "Can only analyze symmetry of crystal structures at present.") sga = SpacegroupAnalyzer(struct_or_mol, symprec=symprec, angle_tolerance=angle_tolerance) try: data = {} data["Crystal System"] = sga.get_crystal_system().title() data["Lattice System"] = sga.get_lattice_type().title() data["Hall Number"] = sga.get_hall() data["International Number"] = sga.get_space_group_number() data["Symbol"] = unicodeify_spacegroup( sga.get_space_group_symbol()) data["Point Group"] = unicodeify_spacegroup( sga.get_point_group_symbol()) sym_struct = sga.get_symmetrized_structure() except: return html.Span( f"Failed to calculate symmetry with this combination of " f"symmetry-finding ({symprec}) and angle tolerances ({angle_tolerance})." ) datalist = get_data_list(data) wyckoff_contents = [] wyckoff_data = sorted( zip(sym_struct.wyckoff_symbols, sym_struct.equivalent_sites), key=lambda x: "".join(filter(lambda w: w.isalpha(), x[0])), ) for symbol, equiv_sites in wyckoff_data: wyckoff_contents.append( html.Label( f"{symbol}, {unicodeify_species(equiv_sites[0].species_string)}", className="mpc-label", )) site_data = [( pretty_frac_format(site.frac_coords[0]), pretty_frac_format(site.frac_coords[1]), pretty_frac_format(site.frac_coords[2]), ) for site in equiv_sites] wyckoff_contents.append(get_table(site_data)) return Columns([ Column([H5("Overview"), datalist]), Column([H5("Wyckoff Positions"), html.Div(wyckoff_contents)]), ])
derv_properties.update(structure_lattice_beta) derv_properties.update(structure_lattice_c) derv_properties.update(structure_lattice_gamma) derv_properties.update(structure_lattice_matrix_0_0) derv_properties.update(structure_lattice_matrix_0_1) derv_properties.update(structure_lattice_matrix_0_2) derv_properties.update(structure_lattice_matrix_1_0) derv_properties.update(structure_lattice_matrix_1_1) derv_properties.update(structure_lattice_matrix_1_2) derv_properties.update(structure_lattice_matrix_2_0) derv_properties.update(structure_lattice_matrix_2_1) derv_properties.update(structure_lattice_matrix_2_2) derv_properties.update(structure_lattice_volume) ## not yet updated for learning (2017-08-29) derv_spacegroup_hall = {"spacegroup_hall": spacegroup.get_hall()} derv_spacegroup_crystal_system = { "spacegroup_crystal_system": spacegroup.get_crystal_system() } derv_spacegroup_groupsymbol = { "spacegroup_symbol": spacegroup.get_space_group_symbol() } derv_spacegroup_point_group = { "spacegroup_point_group": spacegroup.get_point_group_symbol() } derv_properties.update(derv_spacegroup_hall) derv_properties.update(derv_spacegroup_crystal_system) derv_properties.update(derv_spacegroup_groupsymbol) derv_properties.update(derv_spacegroup_point_group) #add electronegativity derv_avg_electroneg = {"electronegativity": ps.composition.average_electroneg}
class SpacegroupAnalyzerTest(PymatgenTest): def setUp(self): p = Poscar.from_file( os.path.join(PymatgenTest.TEST_FILES_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, 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) self.structure4 = graphite def test_primitive(self): s = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]]) a = SpacegroupAnalyzer(s) self.assertEqual(len(s), 4) self.assertEqual(len(a.find_primitive()), 1) def test_is_laue(self): s = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]]) a = SpacegroupAnalyzer(s) self.assertTrue(a.is_laue()) def test_magnetic(self): lfp = PymatgenTest.get_structure("LiFePO4") sg = SpacegroupAnalyzer(lfp, 0.1) self.assertEqual(sg.get_space_group_symbol(), "Pnma") magmoms = [0] * len(lfp) magmoms[4] = 1 magmoms[5] = -1 magmoms[6] = 1 magmoms[7] = -1 lfp.add_site_property("magmom", magmoms) sg = SpacegroupAnalyzer(lfp, 0.1) self.assertEqual(sg.get_space_group_symbol(), "Pnma") def test_get_space_symbol(self): self.assertEqual(self.sg.get_space_group_symbol(), "Pnma") self.assertEqual(self.disordered_sg.get_space_group_symbol(), "P4_2/nmc") self.assertEqual(self.sg3.get_space_group_symbol(), "Pnma") self.assertEqual(self.sg4.get_space_group_symbol(), "P6_3/mmc") def test_get_space_number(self): self.assertEqual(self.sg.get_space_group_number(), 62) self.assertEqual(self.disordered_sg.get_space_group_number(), 137) self.assertEqual(self.sg4.get_space_group_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_symbol(), "mmm") self.assertEqual(self.disordered_sg.get_point_group_symbol(), "4/mmm") def test_get_symmetry_operations(self): for sg, structure in [(self.sg, self.structure), (self.sg4, self.structure4)]: pgops = sg.get_point_group_operations() fracsymmops = sg.get_symmetry_operations() symmops = sg.get_symmetry_operations(True) latt = structure.lattice for fop, op, pgop in zip(fracsymmops, symmops, pgops): # translation vector values should all be 0 or 0.5 t = fop.translation_vector * 2 self.assertArrayAlmostEqual(t - np.round(t), 0) self.assertArrayAlmostEqual(fop.rotation_matrix, pgop.rotation_matrix) for site in 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, newcart, latt, coords_are_cartesian=True) for testsite in structure: if newsite.is_periodic_image(testsite, 1e-3): found = True break self.assertTrue(found) # Make sure this works for any position, not just the atomic # ones. random_fcoord = np.random.uniform(size=(3)) random_ccoord = latt.get_cartesian_coords(random_fcoord) newfrac = fop.operate(random_fcoord) newcart = op.operate(random_ccoord) self.assertTrue( np.allclose(latt.get_fractional_coords(newcart), newfrac)) 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()) orig_spg = self.sg._space_group_data["number"] self.sg._space_group_data["number"] = 0 try: crystal_system = self.sg.get_crystal_system() except ValueError as exc: self.assertEqual(str(exc), "Received invalid space group 0") finally: self.sg._space_group_data["number"] = orig_spg 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) structure = self.get_structure("Li2O") structure.add_site_property("magmom", [1.0] * len(structure)) sg = SpacegroupAnalyzer(structure, 0.01) refined_struct = sg.get_refined_structure(keep_site_properties=True) self.assertEqual(refined_struct.site_properties["magmom"], [1.0] * len(refined_struct)) structure = self.get_structure("Li2O") structure.add_site_property("magmom", [1.0] * len(structure)) sg = SpacegroupAnalyzer(structure, 0.01) refined_struct = sg.get_refined_structure(keep_site_properties=False) self.assertEqual(refined_struct.site_properties.get("magmom", None), None) 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) self.assertEqual(symm_struct.wyckoff_symbols[0], "16h") # self.assertEqual(symm_struct[0].wyckoff, "16h") # Check copying self.assertEqual(symm_struct.copy(), symm_struct) d = symm_struct.as_dict() from pymatgen.symmetry.structure import SymmetrizedStructure ss = SymmetrizedStructure.from_dict(d) self.assertEqual(ss.wyckoff_symbols[0], "16h") self.assertIn("SymmetrizedStructure", ss.__str__()) def test_find_primitive(self): """ F m -3 m Li2O testing of converting to primitive cell """ parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_DIR, "Li2O.cif")) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure) primitive_structure = s.find_primitive() self.assertEqual(primitive_structure.formula, "Li2 O1") self.assertTrue( primitive_structure.site_properties.get("magmom", None) is None) # 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) structure = parser.get_structures(False)[0] structure.add_site_property("magmom", [1.0] * len(structure)) s = SpacegroupAnalyzer(structure) primitive_structure = s.find_primitive(keep_site_properties=True) self.assertEqual(primitive_structure.site_properties["magmom"], [1.0] * len(primitive_structure)) structure = parser.get_structures(False)[0] structure.add_site_property("magmom", [1.0] * len(structure)) s = SpacegroupAnalyzer(structure) primitive_structure = s.find_primitive(keep_site_properties=False) self.assertEqual( primitive_structure.site_properties.get("magmom", None), None) def test_get_ir_reciprocal_mesh(self): grid = self.sg.get_ir_reciprocal_mesh() self.assertEqual(len(grid), 216) self.assertAlmostEqual(grid[1][0][0], 0.1) self.assertAlmostEqual(grid[1][0][1], 0.0) self.assertAlmostEqual(grid[1][0][2], 0.0) self.assertAlmostEqual(grid[1][1], 2) def test_get_conventional_standard_structure(self): parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_DIR, "orac_632475.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, 3.1790663399999999) self.assertAlmostEqual(conv.lattice.b, 9.9032878699999998) self.assertAlmostEqual(conv.lattice.c, 3.5372412099999999) parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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) structure = Structure.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "tric_684654.json")) s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure() self.assertAlmostEqual(conv.lattice.alpha, 74.09581916308757) self.assertAlmostEqual(conv.lattice.beta, 75.72817279281173) self.assertAlmostEqual(conv.lattice.gamma, 63.63234318667333) self.assertAlmostEqual(conv.lattice.a, 3.741372924048738) self.assertAlmostEqual(conv.lattice.b, 3.9883228679270686) self.assertAlmostEqual(conv.lattice.c, 7.288495840048958) structure = Structure.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "tric_684654.json")) structure.add_site_property("magmom", [1.0] * len(structure)) s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure(keep_site_properties=True) self.assertEqual(conv.site_properties["magmom"], [1.0] * len(conv)) structure = Structure.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "tric_684654.json")) structure.add_site_property("magmom", [1.0] * len(structure)) s = SpacegroupAnalyzer(structure, symprec=1e-2) conv = s.get_conventional_standard_structure( keep_site_properties=False) self.assertEqual(conv.site_properties.get("magmom", None), None) def test_get_primitive_standard_structure(self): parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_DIR, "orac_632475.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, 144.40557588533386) self.assertAlmostEqual(prim.lattice.a, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.b, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.c, 3.5372412099999999) parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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(PymatgenTest.TEST_FILES_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) parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_DIR, "rhomb_3478_conv.cif")) structure = parser.get_structures(False)[0] structure.add_site_property("magmom", [1.0] * len(structure)) s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure(keep_site_properties=True) self.assertEqual(prim.site_properties["magmom"], [1.0] * len(prim)) parser = CifParser( os.path.join(PymatgenTest.TEST_FILES_DIR, "rhomb_3478_conv.cif")) structure = parser.get_structures(False)[0] structure.add_site_property("magmom", [1.0] * len(structure)) s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure(keep_site_properties=False) self.assertEqual(prim.site_properties.get("magmom", None), None) 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(PymatgenTest.TEST_FILES_DIR, "POSCAR.tricky_symmetry")) sa = SpacegroupAnalyzer(s, 0.1) sa.get_space_group_symbol() sa.get_space_group_number() sa.get_point_group_symbol() sa.get_crystal_system() sa.get_hall()
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) self.structure4 = graphite def test_primitive(self): s = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]]) a = SpacegroupAnalyzer(s) self.assertEqual(len(s), 4) self.assertEqual(len(a.find_primitive()), 1) def test_is_laue(self): s = Structure.from_spacegroup("Fm-3m", np.eye(3) * 3, ["Cu"], [[0, 0, 0]]) a = SpacegroupAnalyzer(s) self.assertTrue(a.is_laue()) def test_magnetic(self): lfp = PymatgenTest.get_structure("LiFePO4") sg = SpacegroupAnalyzer(lfp, 0.1) self.assertEqual(sg.get_space_group_symbol(), "Pnma") magmoms = [0] * len(lfp) magmoms[4] = 1 magmoms[5] = -1 magmoms[6] = 1 magmoms[7] = -1 lfp.add_site_property("magmom", magmoms) sg = SpacegroupAnalyzer(lfp, 0.1) self.assertEqual(sg.get_space_group_symbol(), "Pnma") def test_get_space_symbol(self): self.assertEqual(self.sg.get_space_group_symbol(), "Pnma") self.assertEqual(self.disordered_sg.get_space_group_symbol(), "P4_2/nmc") self.assertEqual(self.sg3.get_space_group_symbol(), "Pnma") self.assertEqual(self.sg4.get_space_group_symbol(), "P6_3/mmc") def test_get_space_number(self): self.assertEqual(self.sg.get_space_group_number(), 62) self.assertEqual(self.disordered_sg.get_space_group_number(), 137) self.assertEqual(self.sg4.get_space_group_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_symbol(), 'mmm') self.assertEqual(self.disordered_sg.get_point_group_symbol(), '4/mmm') def test_get_symmetry_operations(self): coordinates = np.array([[0.5, 0.0, 0.0], [0.0, 0.5, 0.0], [0.5, 1.0, 0.0], [1.0, 0.5, 0.0]]) species = ['H'] * len(coordinates) molecule = Molecule(species, coordinates) so = PointGroupAnalyzer(molecule, 0.3).get_symmetry_operations() self.assertEqual(len(so), 16) # D4h contains 16 symmetry elements for o in so: self.assertEqual(isinstance(o, SymmOp), True) 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): for sg, structure in [(self.sg, self.structure), (self.sg4, self.structure4)]: pgops = sg.get_point_group_operations() fracsymmops = sg.get_symmetry_operations() symmops = sg.get_symmetry_operations(True) latt = structure.lattice for fop, op, pgop in zip(fracsymmops, symmops, pgops): # translation vector values should all be 0 or 0.5 t = fop.translation_vector * 2 self.assertArrayAlmostEqual(t - np.round(t), 0) self.assertArrayAlmostEqual(fop.rotation_matrix, pgop.rotation_matrix) for site in 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 structure: if newsite.is_periodic_image(testsite, 1e-3): found = True break self.assertTrue(found) # Make sure this works for any position, not just the atomic # ones. random_fcoord = np.random.uniform(size=(3)) random_ccoord = latt.get_cartesian_coords(random_fcoord) newfrac = fop.operate(random_fcoord) newcart = op.operate(random_ccoord) self.assertTrue( np.allclose(latt.get_fractional_coords(newcart), newfrac)) 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.01) 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) self.assertEqual(symm_struct.wyckoff_symbols[0], '16h') # self.assertEqual(symm_struct[0].wyckoff, "16h") 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.assertAlmostEqual(grid[1][0][0], 0.1) self.assertAlmostEqual(grid[1][0][1], 0.0) self.assertAlmostEqual(grid[1][0][2], 0.0) self.assertAlmostEqual(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, 'orac_632475.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, 3.1790663399999999) self.assertAlmostEqual(conv.lattice.b, 9.9032878699999998) self.assertAlmostEqual(conv.lattice.c, 3.5372412099999999) 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, 'orac_632475.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, 144.40557588533386) self.assertAlmostEqual(prim.lattice.a, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.b, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.c, 3.5372412099999999) 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)
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)