Source code for EPWpy.EPWpy_analysis

import numpy as np
#import scipy
import os
from EPWpy.utilities.set_files import *
from EPWpy.utilities.constants import *
from EPWpy.utilities.kramers_kronig import *
from EPWpy.utilities.EPW_util import *
import EPWpy.utilities.walk_path as EP_util

[docs] class PyAnalysis: """ The **PyAnalysis** class provides tools for organizing, accessing, and analyzing output data from various stages of an EPWpy workflow. It serves as a unified interface to handle results generated by *Quantum ESPRESSO (QE)* and *EPW* runs, allowing seamless post-processing and data-driven analysis. Parameters ---------- epw_fold : str, optional Directory name containing EPW output files. Default is `'epw'`. ph_fold : str, optional Directory name containing phonon calculation outputs (e.g., `ph.x`). Default is `'ph'`. scf_fold : str, optional Directory name containing self-consistent field (SCF) calculation outputs. Default is `'scf'`. nscf_fold : str, optional Directory name containing non-self-consistent field (NSCF) calculation outputs. Default is `'nscf'`. data : object, optional Optional data structure or object containing preloaded simulation results, typically an EPWpy data dictionary or custom data container. Default is `None`. Attributes ---------- epw_fold : str Path or folder name for EPW results. ph_fold : str Path or folder name for phonon results. scf_fold : str Path or folder name for SCF results. nscf_fold : str Path or folder name for NSCF results. data : object or None Stores parsed or user-provided data for further analysis. Examples -------- >>> from epwpy.analysis import PyAnalysis >>> analysis = PyAnalysis(epw_fold='epw_out', scf_fold='scf', nscf_fold='nscf') >>> print(analysis.epw_fold) 'epw_out' >>> # Example with preloaded EPWpy data >>> results = {'fermi_level': 5.23, 'bands': [1.2, 2.1, 3.5]} >>> analysis = PyAnalysis(data=results) >>> analysis.data['fermi_level'] 5.23 Notes ----- - This class is typically used after a set of EPWpy simulations have completed, to streamline analysis across multiple subfolders. - Future extensions may include parsing routines for band structures, phonon dispersions, and electron-phonon coupling results. """ def __init__(self, system = './', epw_fold='epw', ph_fold='ph', scf_fold='scf', nscf_fold='nscf', data=None): """ Initialize a PyAnalysis instance. Parameters ---------- epw_fold : str, optional Folder name for EPW output data. ph_fold : str, optional Folder name for phonon output data. scf_fold : str, optional Folder name for SCF output data. nscf_fold : str, optional Folder name for NSCF output data. data : object, optional Preloaded results or user-supplied dataset. """ self.home = os.getcwd() self.system = system self.data = data self.epw_fold = epw_fold self.scf_fold = scf_fold self.ph_fold = ph_fold self.nscf_fold = nscf_fold
[docs] def show_folders(self, system='./'): """ Shows all folders """ print(system) EP_util.print_tree(system, show_files=False)
[docs] def show_files(self, system='./'): """ Shows all files """ print(system) EP_util.print_tree(system, show_files=True)
[docs] def display_file(self, file=None): """ Shows all files """ if file is None: print('No file chosem') else: EP_util.print_file(file)
@property def alpha(self): self.set_work() try: T=self.temp#default_epw_input['temps'] except ValueError: print('key not found') if('lindabs' in self.epw_params.keys()): eps = np.loadtxt(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K.dat') #eps_dir = np.loadtxt(f'{self.epw_fold}/epsilon2_dirabs_'+str(T)+'K.dat') if('loptabs' in self.epw_params.keys()): eps = np.loadtxt(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K_'+self.epw_params['meshnum']+'.dat') alpha=eps[:,0]*eps[:,1]/(hbar*c*self.nr) self.set_home() return(alpha) @property def eps1(self): self.set_work() T=self.temp if('lindabs' in self.epw_params.keys()): _,eps_real,_,_=calc_epr_real(f'{self.epw_file}/epsilon2_indabs_'+str(T)+'K.dat',self.eps0,100) if('loptabs' in self.epw_params.keys()): _,eps_real,_,_=calc_epr_real(f'{self.epw_file}/epsilon2_indabs_'+str(T)+'K_'+self.epw_params['meshnum']+'.dat',self.eps0,100) self.set_home() return(eps_real) @property def nr(self,type_run='indabs'): self.set_work() T=self.temp#default_epw_input['temps'] if('lindabs' in self.epw_params.keys()): nr,eps_real,_,_=calc_epr_real(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K.dat',self.eps0,100) if('loptabs' in self.epw_params.keys()): nr,eps_real,_,_=calc_epr_real(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K_'+self.default_epw_input['meshnum']+'.dat',self.eps0,100) self.set_home() return(nr) @property def eps2(self,type_run='indabs'): self.set_work() T=self.temp#default_epw_input['temps'] if('lindabs' in self.epw_params.keys()): _,_,eps2,_=calc_epr_real(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K.dat',self.eps0,100) if('loptabs' in self.epw_params.keys()): _,_,eps2,_=calc_epr_real(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K_'+self.default_epw_input['meshnum']+'.dat',self.eps0,100) self.set_home() return(eps2) @property def omega(self,type_run='indabs'): self.set_work() T=self.temp#default_epw_input['temps'] if('lindabs' in self.epw_params.keys()): _,_,_,omega=calc_epr_real(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K.dat',self.eps0,100) if('loptabs' in self.epw_params.keys()): _,_,_,omega=calc_epr_real(f'{self.epw_fold}/epsilon2_indabs_'+str(T)+'K_'+self.default_epw_input['meshnum']+'.dat',self.eps0,100) self.set_home() return(omega) @property def inv_tau(self): self.set_work() T=self.temp inv_tau=np.loadtxt(f'{self.epw_fold}/inv_tau.fmt') inv_tau[:,3]=inv_tau[:,3]*13.6 inv_tau[:,4]=inv_tau[:,4]*20670.6944033 self.set_home() return(inv_tau) @property def inv_taucb(self): self.set_work() T=self.temp inv_tau=np.loadtxt(f'{self.epw_fold}/inv_taucb.fmt') inv_tau[:,3]=inv_tau[:,3]*13.6 inv_tau[:,4]=inv_tau[:,4]*20670.6944033 self.set_home() return(inv_tau) @property def inv_tauvb(self): self.set_work() T=self.temp inv_tau=np.loadtxt(f'{self.epw_fold}/inv_tauvb.fmt') inv_tau[:,3]=inv_tau[:,3]*13.6 inv_tau[:,4]=inv_tau[:,4]*20670.6944033 self.set_home() return(inv_tau) @property def inv_taucb_freq(self): self.set_work() self.set_home() @property def abs_calc(self): system=self.system prefix=self.prefix fileimag =str(os.getcwd())+'/'+f"{system}/eps/epsi_{prefix}.dat" filereal =str(os.getcwd())+'/'+f"{system}/eps/epsr_{prefix}.dat" Ei, xi, yi, zi = np.loadtxt(fileimag, usecols=[0, 1, 2, 3], unpack=True,skiprows=2) Er, xr, yr, zr = np.loadtxt(filereal, usecols=[0, 1, 2, 3], unpack=True,skiprows=2) Im = (xi+yi+zi)/3 Re = (xr+yr+zr)/3 def abs(Er,Im,Re): h_cut = 6.58211915561E-16 # eV*s c = 299792458 # m/s delta = (np.sqrt(Re**2 + Im**2) - Re)#/2 abs = (np.sqrt(2)/(h_cut*c))*Er*np.sqrt(delta) return abs output = open(str(os.getcwd())+'/'+f"{system}/eps/abs.dat", 'w') for i in range(0,len(Er),1): coef = abs(Er[i],Im[i],Re[i]) print(Er[i],coef,file = output) output.close() @property def Eform(self): self.set_work() Ef = read_plrn(f'{self.epw_fold}/{self.epw_file}.out') self.set_home() return(Ef) @property def ibte_mobility_e(self): self.set_work() _,ibte_mob = read_mobility(f'{self.epw_fold}/{self.epw_file}',float(self.epw_params['temps'])) self.set_home() return(ibte_mob) @property def serta_mobility_e(self): self.set_work() serta_mob,_ = read_mobility(f'{self.epw_fold}/{self.epw_file}',float(self.epw_params['temps'])) self.set_home() return(serta_mob) @property def ibte_mobility_h(self): self.set_work() _,ibte_mob = read_mobility(f'{self.epw_fold}/{self.epw_file}',float(self.epw_params['temps']),typ='Hole') self.set_home() return(ibte_mob) @property def serta_mobility_h(self): self.set_work() serta_mob,_ = read_mobility(f'{self.epw_fold}/{self.epw_file}',float(self.epw_params['temps']),typ = 'Hole') self.set_home() return(serta_mob) @property def gkk(self): self.EPW_util = EPWProperties(f'{self.epw_fold}/{self.epw_file}') self.set_work() gkk = self.EPW_util.gkk self.set_home() return(gkk)
[docs] def set_home(self): os.chdir(self.home)
[docs] def set_work(self): os.chdir(self.home+'/'+self.system)
[docs] def read_plrn(file1): with open(file1, 'r') as f: for line in f: if( len(line.split())>0 ): if( line.split()[0] =='Formation'): Eform=float(line.split()[3]) return(Eform)
[docs] def read_mobility(file1, T, typ='Elec'): read_mob_serta = False read_mob_ibte = False read_serta = False read_ibte = False serta_mob=np.zeros((3,3),dtype=float) ibte_mob=np.zeros((3,3),dtype=float) temp_found = False t = 0 with open(f'{file1}.out', 'r') as f: for line in f: if ((len(line.split()) != 0) & (read_mob_serta == True)): try: if((float(line.split()[0]) == T) & (t == 0)): temp_found = True if(temp_found == True): serta_mob[t,:] = np.array(line.split()).astype(float)[-3:] t +=1 if(t == 3): read_mob_serta = False read_serta = False t = 0 temp_found = False except ValueError: pass if ((len(line.split()) != 0) & (read_mob_ibte == True)): try: if((float(line.split()[0]) == T) & (t == 0)): temp_found = True if(temp_found == True): ibte_mob[t,:] = np.array(line.split()).astype(float)[-3:] t +=1 if(t == 3): read_mob_ibte = False t = 0 temp_found = False except ValueError: pass if ('SERTA' in line): read_serta = True if ('Iteration number' in line): read_ibte = True if (f'Drift {typ} mobility' in line): if(read_serta == True) : read_mob_serta = True elif(read_ibte == True): read_mob_ibte = True f.close() return(serta_mob, ibte_mob)