def setUp(self): with open(os.path.join(test_dir, 'si_dos.json'), 'r') as sDOS: si_dos = CompleteDos.from_dict(json.load(sDOS)) self.df = pd.DataFrame({'dos': [si_dos], 'site': [0]}) with open(os.path.join(test_dir, 'nb3sn_dos.json'), 'r') as sDOS: nb3sn_dos = CompleteDos.from_dict(json.load(sDOS)) self.nb3sn_df = pd.DataFrame({'dos': [nb3sn_dos]})
def get_dos(self, task_id): m_task = self.collection.find_one({"task_id": task_id}, {"calcs_reversed": 1}) fs_id = m_task['calcs_reversed'][0]['dos_fs_id'] fs = gridfs.GridFS(self.db, 'dos_fs') dos_json = zlib.decompress(fs.get(fs_id).read()) dos_dict = json.loads(dos_json.decode()) return CompleteDos.from_dict(dos_dict)
def setUp(self): self.vbm_val = 2.6682 self.gap = 1.5 self.entries = list(loadfn(os.path.join(os.path.dirname(__file__), "GaAs_test_defentries.json")).values()) for entry in self.entries: entry.parameters.update( {'vbm': self.vbm_val}) self.pd = DefectPhaseDiagram(self.entries, self.vbm_val, self.gap) self.mu_elts = {Element("As"): -4.658070555, Element("Ga"): -3.7317319750000006} # make Vac_As (q= -2) only defect test single-stable-charge exceptions self.extra_entry = DefectEntry(self.entries[5].defect.copy(), 100.) sep_entries = [ent for ent in self.entries if not (ent.name == 'Vac_As_mult4' and ent.charge in [-2,-1,0,1,2])] sep_entries.append( self.extra_entry.copy()) self.sep_pd = DefectPhaseDiagram( sep_entries, self.vbm_val, self.gap) # make Vac_As (q= -2) is incompatible for larger supercell ls_entries = self.entries[:] for entry in ls_entries: if entry.name == 'Vac_As_mult4' and entry.charge == -2.: entry.parameters['is_compatible'] = False self.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=True) self.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=False) # load complete dos for fermi energy solving with open(os.path.join(test_dir, "complete_dos.json"), "r") as f: dos_dict = json.load(f) self.dos = CompleteDos.from_dict(dos_dict)
def setUp(self): with open(os.path.join(test_dir, "complete_dos.json"), "r", encoding='utf-8') as f: self.dos = CompleteDos.from_dict(json.load(f)) self.plotter = DosPlotter(sigma=0.2, stack=True) warnings.simplefilter("ignore")
def setUp(self): with open(os.path.join(PymatgenTest.TEST_FILES_DIR, "complete_dos.json"), encoding="utf-8") as f: self.dos = CompleteDos.from_dict(json.load(f)) self.plotter = DosPlotter(sigma=0.2, stack=True) warnings.simplefilter("ignore")
def setUpClass(cls): cls.vbm_val = 2.6682 cls.gap = 1.5 cls.entries = list(loadfn(os.path.join(os.path.dirname(__file__), "GaAs_test_defentries.json")).values()) for entry in cls.entries: entry.parameters.update({"vbm": cls.vbm_val}) cls.pd = DefectPhaseDiagram(cls.entries, cls.vbm_val, cls.gap) cls.mu_elts = {Element("As"): -4.658070555, Element("Ga"): -3.7317319750000006} # make Vac_As (q= -2) only defect test single-stable-charge exceptions cls.extra_entry = DefectEntry(cls.entries[5].defect.copy(), 100.0) sep_entries = [ ent for ent in cls.entries if not (ent.name == "Vac_As_mult4" and ent.charge in [-2, -1, 0, 1, 2]) ] sep_entries.append(cls.extra_entry.copy()) cls.sep_pd = DefectPhaseDiagram(sep_entries, cls.vbm_val, cls.gap) # make Vac_As (q= -2) is incompatible for larger supercell ls_entries = cls.entries[:] for entry in ls_entries: if entry.name == "Vac_As_mult4" and entry.charge == -2.0: entry.parameters["is_compatible"] = False cls.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries, cls.vbm_val, cls.gap, filter_compatible=True) cls.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries, cls.vbm_val, cls.gap, filter_compatible=False) # load complete dos for fermi energy solving with open(os.path.join(PymatgenTest.TEST_FILES_DIR, "complete_dos.json")) as f: dos_dict = json.load(f) cls.dos = CompleteDos.from_dict(dos_dict)
def _get_cdos(pdos_file, site_file): if not (pdos_file and site_file): raise ValueError('Both dos.ext and site.ext are needed for PDOS') energies, data, efermi, nsp = _read_dos_data(pdos_file) if nsp == 1: fake_tdos = Dos(efermi, energies, {Spin.up: 0 * energies}) spins = (Spin.up, ) elif nsp == 2: fake_tdos = Dos(efermi, energies, { Spin.up: 0 * energies, Spin.down: 0 * energies }) spins = (Spin.up, Spin.down) else: raise ValueError('There can\'t be {} spin channels, that makes ' 'no sense!'.format(nsp)) site_data = QuestaalSite.from_file(site_file) structure = site_data.structure pdoss = {} for site, orbital, spin in product( range(len(site_data.sites)), range(16), # forget about g orbs range(len(spins))): if structure.sites[site] not in pdoss: pdoss.update({structure.sites[site]: {}}) if Orbital(orbital) not in pdoss[structure.sites[site]]: pdoss[structure.sites[site]].update({Orbital(orbital): {}}) pdoss[structure.sites[site]][Orbital(orbital)].update( {spins[spin]: data[site * (25 * nsp) + orbital * nsp + spin]}) return CompleteDos(structure, fake_tdos, pdoss)
def merge_up_down_doses(dos_up, dos_dn): """ Merge the up and down DOSs. Args: dos_up: Up DOS. dos_dn: Down DOS Return: CompleteDos object """ warnings.warn("This function is not useful anymore. VasprunBSLoader deals \ with spin case.") cdos = Dos( dos_up.efermi, dos_up.energies, { Spin.up: dos_up.densities[Spin.up], Spin.down: dos_dn.densities[Spin.down] }, ) if hasattr(dos_up, "pdos") and hasattr(dos_dn, "pdos"): pdoss = {} for site in dos_up.pdos: pdoss.setdefault(site, {}) for orb in dos_up.pdos[site]: pdoss[site].setdefault(orb, {}) pdoss[site][orb][Spin.up] = dos_up.pdos[site][orb][Spin.up] pdoss[site][orb][Spin.down] = dos_dn.pdos[site][orb][Spin.down] cdos = CompleteDos(dos_up.structure, total_dos=cdos, pdoss=pdoss) return cdos
def get_dos_from_id(self, task_id): """ Overrides the get_dos_from_id for the MIT gridfs format. """ args = {'task_id': task_id} fields = ['calculations'] structure = self.get_structure_from_id(task_id) dosid = None for r in self.query(fields, args): dosid = r['calculations'][-1]['dos_fs_id'] if dosid is not None: self._fs = gridfs.GridFS(self.db, 'dos_fs') with self._fs.get(dosid) as dosfile: s = dosfile.read() try: d = json.loads(s) except: s = zlib.decompress(s) d = json.loads(s.decode("utf-8")) tdos = Dos.from_dict(d) pdoss = {} for i in range(len(d['pdos'])): ados = d['pdos'][i] all_ados = {} for j in range(len(ados)): orb = Orbital(j) odos = ados[str(orb)] all_ados[orb] = {Spin(int(k)): v for k, v in odos['densities'].items()} pdoss[structure[i]] = all_ados return CompleteDos(structure, tdos, pdoss) return None
def extract_dos(mat): dos = None if "dos" in mat["bandstructure"]: dos_dict = mat["bandstructure"]["dos"] dos = CompleteDos.from_dict(dos_dict) return dos
def setUp(self): try: import scipy except ImportError: raise SkipTest("scipy not present. Skipping...") with open(os.path.join(test_dir, "complete_dos.json"), "r") as f: self.dos = CompleteDos.from_dict(json.load(f)) self.plotter = DosPlotter(sigma=0.2, stack=True)
def get_bs(dos, vasprun_bands, kpts_bands): ## get BandStructureSymmLine object and "save" in hidden div in json format bands = Vasprun(vasprun_bands, parse_projected_eigen = True) if dos: dos = CompleteDos.from_dict(json.loads(dos)) bs = bands.get_band_structure(kpts_bands, line_mode=True, efermi=dos.efermi) else: bs = bands.get_band_structure(kpts_bands, line_mode=True) return json.dumps(bs.as_dict(), cls=MyEncoder)
def from_dict(complete_dos_dict): """ Returns FeffLdos object from dict representation. Args: complete_dos_dict: dict representation os complete_dos """ complete_dos = CompleteDos.from_dict(complete_dos_dict) return FeffLdos(complete_dos)
def from_dict(d): """ Returns FeffLdos object from dict representation Args: complete_dos: dict representation of complete_dos """ complete_dos = CompleteDos.from_dict(d['complete_dos']) charge_transfer = d['charge_transfer'] return FeffLdos(complete_dos, charge_transfer)
def update_dosbandsfig(n_clicks, dos, bs, projlist): ## figure updates when the inputs change or the button is clicked ## figure does NOT update when elements or orbitals are selected ## de-serialize dos and bs from json format to pymatgen objects if dos: dos = CompleteDos.from_dict(json.loads(dos)) if bs: bs = BandStructureSymmLine.from_dict(json.loads(bs)) ## update the band structure and dos figure dosbandfig = BandsFig().generate_fig(dos, bs, projlist) return dosbandfig
def get_dos(self, task_id): """ Read the DOS data into a PMG DOS object Args: task_id(int or str): the task_id containing the data Returns: CompleteDos object """ obj_dict = self.get_data_from_maggma_or_gridfs(task_id, key="dos") return CompleteDos.from_dict(obj_dict)
def featurize(self, dos): """ Args: dos (pymatgen CompleteDos or their dict): The density of states to featurize. Must be a complete DOS, (i.e. contains PDOS and structure, in addition to total DOS) and must contain the structure. Returns: xbm_score_i (float): fractions of ith contributor orbital xbm_location_i (str): fractional coordinate of ith contributor. For example, '0.0;0.0;0.0' if Gamma xbm_specie_i: (str) elemental specie of ith contributor (ex: 'Ti') xbm_character_i: (str) orbital character of ith contributor (s p d or f) xbm_nsignificant: (int) the number of orbitals with contributions above the significance_threshold """ if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_cbm_vbm_scores(dos, self.energy_cutoff, self.sampling_resolution, self.gaussian_smear) self.feat = {} for ex in ['cbm', 'vbm']: orbscores.sort(key=lambda x: x['{}_score'.format(ex)], reverse=True) scores = np.array([s['{}_score'.format(ex)] for s in orbscores]) self.feat['{}_nsignificant'.format(ex)] = len( scores[scores > self.significance_threshold]) i = 0 while i < self.contributors: sd = orbscores[i] if i < len(orbscores): for p in ['character', 'specie']: self.feat['{}_{}_{}'.format(ex, p, i + 1)] = sd[p] self.feat['{}_location_{}'.format( ex, i + 1)] = '{};{};{}'.format(sd['location'][0], sd['location'][1], sd['location'][2]) self.feat['{}_score_{}'.format(ex, i + 1)] = float( sd['{}_score'.format(ex)]) else: for p in [ '{}_score'.format(ex), 'character', 'specie', 'location' ]: self.feat['{}_{}_{}'.format(ex, p, i + 1)] = float('NaN') i += 1 return list(self.feat.values())
def get_partial_doses(self, tdos, eband_ud, spins, enr, npts_mu, T, progress): """ Return a CompleteDos object interpolating the projections tdos: total dos previously calculated npts_mu: number of energy points of the Dos T: parameter used to smooth the Dos progress: Default False, If True a progress bar is shown. """ if not self.data.proj: raise BoltztrapError("No projections loaded.") bkp_data_ebands = np.copy(self.data.ebands) pdoss = {} if progress: n_iter = np.prod( np.sum( [np.array(i.shape)[2:] for i in self.data.proj.values()])) t = tqdm(total=n_iter * 2) for spin, eb in zip(spins, eband_ud): for isite, site in enumerate(self.data.structure.sites): if site not in pdoss: pdoss[site] = {} for iorb, orb in enumerate(Orbital): if progress: t.update() if iorb == self.data.proj[spin].shape[-1]: break if orb not in pdoss[site]: pdoss[site][orb] = {} self.data.ebands = self.data.proj[spin][:, :, isite, iorb].T coeffs = fite.fitde3D(self.data, self.equivalences) proj, vvproj, cproj = fite.getBTPbands( self.equivalences, coeffs, self.data.lattvec) edos, pdos = BL.DOS(eb, npts=npts_mu, weights=np.abs(proj.real), erange=enr) if T: pdos = BL.smoothen_DOS(edos, pdos, T) pdoss[site][orb][spin] = pdos self.data.ebands = bkp_data_ebands return CompleteDos(self.data.structure, total_dos=tdos, pdoss=pdoss)
def featurize(self, dos, energy_cutoff=None): """ takes in the density of state and return the orbitals contributions and hybridizations. Args: dos (pymatgen CompleteDos): note that dos.structure is required energy_cutoff (float or None): if set, it overrides the instance variable self.energy_cutoff. Returns ([float]): features, see class doc for more info """ energy_cutoff = energy_cutoff or self.energy_cutoff if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_cbm_vbm_scores(dos, energy_cutoff, self.sampling_resolution, self.gaussian_smear) feat = OrderedDict() for ex in ['cbm', 'vbm']: for orbital in ['s', 'p', 'd', 'f']: feat['{}_{}'.format(ex, orbital)] = 0.0 for specie in self.species: feat['{}_{}_{}'.format(ex, specie, orbital)] = 0.0 for hybrid in ['sp', 'sd', 'sf', 'pd', 'pf', 'df']: feat['{}_{}'.format(ex, hybrid)] = 0.0 for contrib in orbscores: character = contrib['character'] feat['cbm_{}'.format(character)] += contrib['cbm_score'] feat['vbm_{}'.format(character)] += contrib['vbm_score'] for specie in self.species: if contrib['specie'] == specie: feat['cbm_{}_{}'.format(specie, character)] += contrib['cbm_score'] feat['vbm_{}_{}'.format(specie, character)] += contrib['vbm_score'] for ex in ['cbm', 'vbm']: for hybrid in ['sp', 'sd', 'sf', 'pd', 'pf', 'df']: orb1 = feat['{}_{}'.format(ex, hybrid[0])] orb2 = feat['{}_{}'.format(ex, hybrid[1])] feat['{}_{}'.format( ex, hybrid)] = (orb1 * orb2) * 4.0 # 4x so max=1.0 return list(feat.values())
def featurize(self, dos, decay_length=None): """ takes in the density of state and return the orbitals contributions and hybridizations. Args: dos (pymatgen CompleteDos): note that dos.structure is required decay_length (float or None): if set, it overrides the instance variable self.decay_length. Returns ([float]): features, see class doc for more info """ decay_length = decay_length or self.decay_length if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_cbm_vbm_scores(dos, decay_length, self.sampling_resolution, self.gaussian_smear) feat = OrderedDict() for ex in ['cbm', 'vbm']: for orbital in ['s', 'p', 'd', 'f']: feat['{}_{}'.format(ex, orbital)] = 0.0 for specie in self.species: feat['{}_{}_{}'.format(ex, specie, orbital)] = 0.0 for hybrid in ['sp', 'sd', 'sf', 'pd', 'pf', 'df']: feat['{}_{}'.format(ex, hybrid)] = 0.0 for contrib in orbscores: character = contrib['character'] feat['cbm_{}'.format(character)] += contrib['cbm_score'] feat['vbm_{}'.format(character)] += contrib['vbm_score'] for specie in self.species: if contrib['specie'] == specie: feat['cbm_{}_{}'.format(specie, character)] += contrib[ 'cbm_score'] feat['vbm_{}_{}'.format(specie, character)] += contrib[ 'vbm_score'] for ex in ['cbm', 'vbm']: for hybrid in ['sp', 'sd', 'sf', 'pd', 'pf', 'df']: orb1 = feat['{}_{}'.format(ex, hybrid[0])] orb2 = feat['{}_{}'.format(ex, hybrid[1])] feat['{}_{}'.format(ex, hybrid)] = (orb1 * orb2) * 4.0 # 4x so max=1.0 return list(feat.values())
def from_dos(cls, dos: CompleteDos): """ :param dos: CompleteDos object with project element-orbital DOS. Can be obtained from Vasprun.get_complete_dos. :param sigma: Smearing for Gaussian. :return: XPS """ total = np.zeros(dos.energies.shape) for el in dos.structure.composition.keys(): spd_dos = dos.get_element_spd_dos(el) for orb, pdos in spd_dos.items(): weight = CROSS_SECTIONS[el.symbol].get(str(orb), None) if weight is not None: total += pdos.get_densities() * weight else: warnings.warn(f"No cross-section for {el}{orb}") return XPS(-dos.energies, total / np.max(total))
def merge_up_down_doses(dos_up, dos_dn): cdos = Dos(dos_up.efermi, dos_up.energies, {Spin.up: dos_up.densities[Spin.up], Spin.down: dos_dn.densities[Spin.down]}) if hasattr(dos_up, 'pdos') and hasattr(dos_dn, 'pdos'): pdoss = {} for site in dos_up.pdos: pdoss.setdefault(site, {}) for orb in dos_up.pdos[site]: pdoss[site].setdefault(orb, {}) pdoss[site][orb][Spin.up] = dos_up.pdos[site][orb][Spin.up] pdoss[site][orb][Spin.down] = dos_dn.pdos[site][orb][Spin.down] cdos = CompleteDos(dos_up.structure, total_dos=cdos, pdoss=pdoss) return cdos
def test_to_from_dict(self): d = self.dos.as_dict() dos = CompleteDos.from_dict(d) el_dos = dos.get_element_dos() self.assertEqual(len(el_dos), 4) spd_dos = dos.get_spd_dos() sum_spd = spd_dos[OrbitalType.s] + spd_dos[OrbitalType.p] + spd_dos[OrbitalType.d] sum_element = None for pdos in el_dos.values(): if sum_element is None: sum_element = pdos else: sum_element += pdos # The sums of the SPD or the element doses should be the same. self.assertTrue((abs(sum_spd.energies - sum_element.energies) < 0.0001).all())
def process_item(self, mat): """ Process the tasks and materials into just a list of materials Args: mat (dict): material document Returns: (dict): electronic_structure document """ d = {self.electronic_structure.key: mat[self.materials.key]} self.logger.info("Processing: {}".format(mat[self.materials.key])) bs = build_bs(mat["bandstructure"]["bs"], mat) dos = CompleteDos.from_dict(mat["bandstructure"]["dos"]) if bs and dos: try: pdos = get_pdos(dos) dos_plotter = SDOSPlotter(dos, pdos) bs_plotter = SBSPlotter(bs) plt = bs_plotter.get_plot(dos_plotter=dos_plotter, **self.plot_options) d["plot"] = image_from_plot(plt) plt.close() except Exception: traceback.print_exc() self.logger.warning( "Caught error in bandstructure plotting for {}: {}".format( mat[self.materials.key], traceback.format_exc())) # Reduced Band structure plot try: gap = bs.get_band_gap()["energy"] plot_data = bs_plotter.bs_plot_data() d["bs_plot_small"] = get_small_plot(plot_data, gap) except Exception: self.logger.warning( "Caught error in generating reduced bandstructure plot for {}: {}" .format(mat[self.materials.key], traceback.format_exc())) # Store task_ids for k in ["bs_task", "dos_task", "uniform_task"]: if k in mat["bandstructure"]: d[k] = mat["bandstructure"][k] return d
def get_partial_doses(self, tdos, npts_mu, T): """ Return a CompleteDos object interpolating the projections tdos: total dos previously calculated npts_mu: number of energy points of the Dos T: parameter used to smooth the Dos """ spin = self.data.spin if isinstance(self.data.spin, int) else 1 if not isinstance(self.data.proj, np.ndarray): raise BoltztrapError("No projections loaded.") bkp_data_ebands = np.copy(self.data.ebands) pdoss = {} # for spin in self.data.proj: for isite, site in enumerate(self.data.structure.sites): if site not in pdoss: pdoss[site] = {} for iorb, orb in enumerate(Orbital): if iorb == self.data.proj.shape[-1]: break if orb not in pdoss[site]: pdoss[site][orb] = {} self.data.ebands = self.data.proj[:, :, isite, iorb].T coeffs = fite.fitde3D(self.data, self.equivalences) proj, vvproj, cproj = fite.getBTPbands(self.equivalences, coeffs, self.data.lattvec) edos, pdos = BL.DOS(self.eband, npts=npts_mu, weights=np.abs(proj.real)) if T is not None: pdos = BL.smoothen_DOS(edos, pdos, T) pdoss[site][orb][Spin(spin)] = pdos self.data.ebands = bkp_data_ebands return CompleteDos(self.data.structure, total_dos=tdos, pdoss=pdoss)
def get_complete_dos(self, structure): """ Gives a CompleteDos object with the DOS from the interpolated projected band structure Args: the structure (necessary to identify sites for projection) Returns: a CompleteDos object """ pdoss = {} for s in self._dos_partial: if structure.sites[int(s)] not in pdoss: pdoss[structure.sites[int(s)]] = {} for o in self._dos_partial[s]: if Orbital.from_string(o) not in pdoss[structure.sites[int(s)]]: pdoss[structure.sites[int(s)]][Orbital.from_string(o)] = {} pdoss[structure.sites[int(s)]][Orbital.from_string(o)][Spin.up] = self._dos_partial[s][o] return CompleteDos(structure, total_dos=self.dos, pdoss=pdoss)
def featurize(self, dos): """ Args: dos (pymatgen CompleteDos or their dict): The density of states to featurize. Must be a complete DOS, (i.e. contains PDOS and structure, in addition to total DOS) and must contain the structure. """ if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_cbm_vbm_scores(dos, self.energy_cutoff, self.sampling_resolution, self.gaussian_smear) feat = OrderedDict() for ex in ['cbm', 'vbm']: orbscores.sort(key=lambda x: x['{}_score'.format(ex)], reverse=True) scores = np.array([s['{}_score'.format(ex)] for s in orbscores]) feat['{}_nsignificant'.format(ex)] = len( scores[scores > self.significance_threshold]) i = 0 while i < self.contributors: sd = orbscores[i] if i < len(orbscores): for p in ['character', 'specie']: feat['{}_{}_{}'.format(ex, p, i + 1)] = sd[p] feat['{}_location_{}'.format(ex, i + 1)] = '{};{};{}'.format( sd['location'][0], sd['location'][1], sd['location'][2]) feat['{}_score_{}'.format(ex, i + 1)] = float( sd['{}_score'.format(ex)]) else: for p in ['character', 'specie', 'location', 'score']: feat['{}_{}_{}'.format(ex, p, i + 1)] = float('NaN') i += 1 return list(feat.values())
def _get_bs_dos(data): data = data or {} # this component can be loaded either from mpid or # directly from BandStructureSymmLine or CompleteDos objects # if mpid is supplied, this is preferred mpid = data.get("mpid") bandstructure_symm_line = data.get("bandstructure_symm_line") density_of_states = data.get("density_of_states") if not mpid and (bandstructure_symm_line is None or density_of_states is None): return None, None if mpid: with MPRester() as mpr: try: bandstructure_symm_line = mpr.get_bandstructure_by_material_id( mpid) except Exception as exc: print(exc) bandstructure_symm_line = None try: density_of_states = mpr.get_dos_by_material_id(mpid) except Exception as exc: print(exc) density_of_states = None else: if bandstructure_symm_line and isinstance(bandstructure_symm_line, dict): bandstructure_symm_line = BandStructureSymmLine.from_dict( bandstructure_symm_line) if density_of_states and isinstance(density_of_states, dict): density_of_states = CompleteDos.from_dict(density_of_states) return bandstructure_symm_line, density_of_states
def featurize(self, dos): """ Args: dos (pymatgen CompleteDos or their dict): The density of states to featurize. Must be a complete DOS, (i.e. contains PDOS and structure, in addition to total DOS) and must contain the structure. """ if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_cbm_vbm_scores(dos, self.decay_length, self.sampling_resolution, self.gaussian_smear) feat = OrderedDict() for ex in ['cbm', 'vbm']: orbscores.sort(key=lambda x: x['{}_score'.format(ex)], reverse=True) scores = np.array([s['{}_score'.format(ex)] for s in orbscores]) feat['{}_hybridization'.format(ex)] = - np.sum( scores * np.log(scores + 1e-10)) # avoid log(0) i = 0 while i < self.contributors: sd = orbscores[i] if i < len(orbscores): for p in ['character', 'specie']: feat['{}_{}_{}'.format(ex, p, i + 1)] = sd[p] feat['{}_location_{}'.format(ex, i + 1)] =\ '{};{};{}'.format(sd['location'][0], sd['location'][1], sd['location'][2]) feat['{}_score_{}'.format(ex, i + 1)] =\ float(sd['{}_score'.format(ex)]) else: for p in ['character', 'specie', 'location', 'score']: feat['{}_{}_{}'.format(ex, p, i + 1)] = float('NaN') i += 1 return list(feat.values())
def setUp(self): self.vbm_val = 2.6682 self.gap = 1.5 self.entries = list( loadfn( os.path.join(os.path.dirname(__file__), "GaAs_test_defentries.json")).values()) for entry in self.entries: entry.parameters.update({'vbm': self.vbm_val}) self.pd = DefectPhaseDiagram(self.entries, self.vbm_val, self.gap) self.mu_elts = { Element("As"): -4.658070555, Element("Ga"): -3.7317319750000006 } # make Vac_As (q= -2) only defect test single-stable-charge exceptions self.extra_entry = DefectEntry(self.entries[5].defect.copy(), 100.) sep_entries = [ ent for ent in self.entries if not ( ent.name == 'Vac_As_mult4' and ent.charge in [-2, -1, 0, 1, 2]) ] sep_entries.append(self.extra_entry.copy()) self.sep_pd = DefectPhaseDiagram(sep_entries, self.vbm_val, self.gap) # make Vac_As (q= -2) is incompatible for larger supercell ls_entries = self.entries[:] for entry in ls_entries: if entry.name == 'Vac_As_mult4' and entry.charge == -2.: entry.parameters['is_compatible'] = False self.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=True) self.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=False) # load complete dos for fermi energy solving with open(os.path.join(test_dir, "complete_dos.json"), "r") as f: dos_dict = json.load(f) self.dos = CompleteDos.from_dict(dos_dict)
def featurize(self, dos, idx): """ get dos scores for given site index Args: dos (pymatgen CompleteDos or their dict): dos to featurize, must contain pdos and structure idx (int): index of target site in structure. """ if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_site_dos_scores(dos, idx, self.decay_length, self.sampling_resolution, self.gaussian_smear) features = [] for edge in ['cbm', 'vbm']: for score in ['s', 'p', 'd', 'f', 'total']: features.append(orbscores[edge][score]) return features
def featurize(self, dos, idx): """ get dos scores for given site index Args: dos (pymatgen CompleteDos or their dict): dos to featurize, must contain pdos and structure idx (int): index of target site in structure. """ if isinstance(dos, dict): dos = CompleteDos.from_dict(dos) if dos.structure is None: raise ValueError('The input dos must contain the structure.') orbscores = get_site_dos_scores(dos, idx, self.fermi_temperature, self.sampling_resolution, self.gaussian_smear) features = [] for edge in ['cbm', 'vbm']: for score in ['s', 'p', 'd', 'f', 'total']: features.append(orbscores[edge][score]) return features
def get_cdos(): for n in range(1, 74): pdos = defaultdict(dict) atom = '' orb = '' for a in atoms: if os.path.exists(f'pwscf.pdos_atm#{n}({a})_wfc#{1}(s)'): atom = Element(a) if atom == '': continue for l, o in enumerate(orbital): if os.path.exists(f'pwscf.pdos_atm#{n}({str(atom)})_wfc#{l + 1}({o})'): orb = OrbitalType(l) data = np.genfromtxt(f'pwscf.pdos_atm#{n}({str(atom)})_wfc#{l + 1}({orb.name})') pdos[orb][Spin.up] = data[:, 1] pdos[orb][Spin.down] = data[:, 2] energies = data[:,0] pdoss.append(pdos) efermi = fermi_fromfile('report.scf') total_density= six.moves.reduce(add_densities, [six.moves.reduce(add_densities, p.values()) for p in pdoss]) total_dos = Dos(efermi, energies, total_density) s = Structure.from_file('123.cif') return CompleteDos(s, total_dos, pdoss)
el: chempots_delta[el] + c.chempots_reference[el] for el in chempots_delta } pressures.append(np.around(partial_pressure, decimals=4)) reservoirs.append(chempots_abs) print('Reading defect calculation data...\n') with open('vacancies_NN_HSE.json') as json_file: data = json.load(json_file) defects_analysis = DefectsAnalysis.from_dict(data) print('Reading DOS...\n') with open('dos_NN_HSE.json') as json_file: data = json.load(json_file) bulk_dos = CompleteDos.from_dict(data) concentrations = [] for r in reservoirs: fermi_energy = defects_analysis.equilibrium_fermi_level(r, bulk_dos) cn = defects_analysis.defect_concentrations_stable_charges( r, temperature=temperature, fermi_level=fermi_energy) concentrations.append(cn) data = { 'partial_pressures': pressures, 'defect_concentrations': concentrations } with open('defect_concentrations_NN_HSE.json', 'w') as json_file:
def setUp(self): with open(os.path.join(test_dir, "complete_dos.json"), "r", encoding='utf-8') as f: self.dos = CompleteDos.from_dict(json.load(f)) self.plotter = DosPlotter(sigma=0.2, stack=True)
def from_file(feff_inp_file="feff.inp", ldos_file="ldos"): """ Creates LDos object from raw Feff ldos files by by assuming they are numbered consecutively, i.e. ldos01.dat ldos02.dat... Args: feff_inp_file (str): input file of run to obtain structure ldos_file (str): output ldos file of run to obtain dos info, etc. """ header_str = Header.header_string_from_file(feff_inp_file) header = Header.from_string(header_str) structure = header.struct nsites = structure.num_sites parameters = Tags.from_file(feff_inp_file) if "RECIPROCAL" in parameters: pot_dict = {} pot_readstart = re.compile(".*iz.*lmaxsc.*xnatph.*xion.*folp.*") pot_readend = re.compile(".*ExternalPot.*switch.*") pot_inp = re.sub(r"feff.inp", r"pot.inp", feff_inp_file) dos_index = 1 begin = 0 with zopen(pot_inp, "r") as potfile: for line in potfile: if len(pot_readend.findall(line)) > 0: break if begin == 1: begin += 1 continue if begin == 2: z_number = int(line.strip().split()[0]) ele_name = Element.from_Z(z_number).name if ele_name not in pot_dict: pot_dict[ele_name] = dos_index else: pot_dict[ele_name] = min(dos_index, pot_dict[ele_name]) dos_index += 1 if len(pot_readstart.findall(line)) > 0: begin = 1 else: pot_string = Potential.pot_string_from_file(feff_inp_file) dicts = Potential.pot_dict_from_string(pot_string) pot_dict = dicts[0] with zopen(ldos_file + "00.dat", "r") as fobject: f = fobject.readlines() efermi = float(f[0].split()[4]) dos_energies = [] ldos = {} for i in range(1, len(pot_dict) + 1): if len(str(i)) == 1: ldos[i] = np.loadtxt(f"{ldos_file}0{i}.dat") else: ldos[i] = np.loadtxt(f"{ldos_file}{i}.dat") for i in range(0, len(ldos[1])): dos_energies.append(ldos[1][i][0]) all_pdos = [] vorb = { "s": Orbital.s, "p": Orbital.py, "d": Orbital.dxy, "f": Orbital.f0 } forb = {"s": 0, "p": 1, "d": 2, "f": 3} dlength = len(ldos[1]) for i in range(nsites): pot_index = pot_dict[structure.species[i].symbol] all_pdos.append(defaultdict(dict)) for k, v in vorb.items(): density = [ ldos[pot_index][j][forb[k] + 1] for j in range(dlength) ] updos = density downdos = None if downdos: all_pdos[-1][v] = {Spin.up: updos, Spin.down: downdos} else: all_pdos[-1][v] = {Spin.up: updos} pdos = all_pdos vorb2 = {0: Orbital.s, 1: Orbital.py, 2: Orbital.dxy, 3: Orbital.f0} pdoss = { structure[i]: {v: pdos[i][v] for v in vorb2.values()} for i in range(len(pdos)) } forb = {"s": 0, "p": 1, "d": 2, "f": 3} tdos = [0] * dlength for i in range(nsites): pot_index = pot_dict[structure.species[i].symbol] for v in forb.values(): density = [ldos[pot_index][j][v + 1] for j in range(dlength)] for j in range(dlength): tdos[j] = tdos[j] + density[j] tdos = {Spin.up: tdos} dos = Dos(efermi, dos_energies, tdos) complete_dos = CompleteDos(structure, dos, pdoss) charge_transfer = LDos.charge_transfer_from_file( feff_inp_file, ldos_file) return LDos(complete_dos, charge_transfer)
def setUp(self): with open(os.path.join(test_dir, "complete_dos.json"), "r") as f: self.dos = CompleteDos.from_dict(json.load(f))
def process_item(self, mat): """ Process the tasks and materials into just a list of materials Args: mat (dict): material document Returns: (dict): electronic_structure document """ self.logger.info("Processing: {}".format(mat[self.materials.key])) d = {self.electronic_structure.key: mat[ self.materials.key], "bandstructure": {}} bs = None dos = None interpolated_dos = None # Process the bandstructure for information if "bs" in mat["bandstructure"]: if "structure" not in mat["bandstructure"]["bs"]: mat["bandstructure"]["bs"]["structure"] = mat["structure"] if len(mat["bandstructure"]["bs"].get("labels_dict", {})) == 0: struc = Structure.from_dict(mat["structure"]) kpath = HighSymmKpath(struc)._kpath["kpoints"] mat["bandstructure"]["bs"]["labels_dict"] = kpath # Somethign is wrong with the as_dict / from_dict encoding in the two band structure objects so have to use this hodge podge serialization # TODO: Fix bandstructure objects in pymatgen bs = BandStructureSymmLine.from_dict( BandStructure.from_dict(mat["bandstructure"]["bs"]).as_dict()) d["bandstructure"]["band_gap"] = {"band_gap": bs.get_band_gap()["energy"], "direct_gap": bs.get_direct_band_gap(), "is_direct": bs.get_band_gap()["direct"], "transition": bs.get_band_gap()["transition"]} if self.small_plot: d["bandstructure"]["plot_small"] = get_small_plot(bs) if "dos" in mat["bandstructure"]: dos = CompleteDos.from_dict(mat["bandstructure"]["dos"]) if self.interpolate_dos and "uniform_bs" in mat["bandstructure"]: try: interpolated_dos = self.get_interpolated_dos(mat) except Exception: self.logger.warning("Boltztrap interpolation failed for {}. Continuing with regular DOS".format(mat[self.materials.key])) # Generate static images if self.static_images: try: ylim = None if bs: plotter = WebBSPlotter(bs) fig = plotter.get_plot() ylim = fig.ylim() # Used by DOS plot fig.close() d["bandstructure"]["bs_plot"] = image_from_plotter(plotter) if dos: plotter = WebDosVertPlotter() plotter.add_dos_dict(dos.get_element_dos()) if interpolated_dos: plotter.add_dos("Total DOS", interpolated_dos) d["bandstructure"]["dos_plot"] = image_from_plotter(plotter, ylim=ylim) d["bandstructure"]["dos_plot"] = image_from_plotter(plotter, ylim=ylim) except Exception: self.logger.warning( "Caught error in electronic structure plotting for {}: {}".format(mat[self.materials.key], traceback.format_exc())) return None return d