Esempio n. 1
0
def bdf_read_band(filename):
    '''
    Read a band structure from bdf output
    '''
    f = open(filename)
    #Read reciporocal vectors
    lines = f.readlines()
    f.close()
    mK = [[float(y) for y in x.split()[1:4]] for x in lines[2:5]]
    eig_fermi = float(lines[6].split()[-1])
    print(eig_fermi)
    list_kpt = []
    list_eig = []
    for line in lines[7:]:
        ar = line.split()
        #"A" is marked as non-special k-points
        if (ar[1] == "A"):
            ar[1] = ""
        list_kpt.append(ar[1:2] + [float(x) for x in ar[2:5]] + [1.0])
        list_eig.append([float(x) for x in ar[5:]])
    kpt = KPointsT()
    kpt.stMode = "crystal"
    kpt.ReadFromList(list_kpt)
    kpt.ConvertUnit("cart", mLatt=f_GetReciprocalLattice(mK))
    band = BandsT(kpt, list_eig, eig_fermi, eig_fermi)
    band.b_metal = True  #Just set to plot fermi
    return band
Esempio n. 2
0
def yaeh_ReadBand(stFileName):
    '''
    Read k-points and band from yaeh band result.
    Fermi energy is not calculated.
    @todo spin is always 1
    '''
    f = open(stFileName)
    ar_stLine = f.readlines()

    list_kp = []
    list_band = []

    nbnd = int(ar_stLine[4].split()[0])  #Number of bands in each kpt
    nStart = 0  #Start position of band data
    for i in range(0, len(ar_stLine)):
        if ("Begin band data" in ar_stLine[i]):
            nStart = i + 1  #line count that not band data
            break

    for i in range(0, (len(ar_stLine) - nStart) / (nbnd + 1)):
        i2 = (nbnd + 1) * i + nStart
        list_kp.append([float(x) for x in ar_stLine[i2][10:].split()])
        list_band.append([float(x) for x in ar_stLine[i2 + 1:i2 + nbnd + 1]])

    #write
    aKPT = KPointsT()
    aKPT.ReadFromList(list_kp)

    #   return aKPT,list_band,0,0,0
    band = BandsT(aKPT, list_band)
    band.num_spin = 1
    return band
Esempio n. 3
0
def abi_ReadBand_EIG(stFileName):
    '''
    Read band structure from _EIG file
    '''
    f = open(stFileName)
    stLine = f.readline()
    if ("hartree" in stLine):  # "(hartree) ="
        energy_unit = Ha2eV
    else:
        energy_unit = 1.0  # energy unit; if it is hartree then convert to eV
    if ("Fermi" in stLine):  # Find the first equal
        ixEqual = stLine.index("=")
        dFermi = float(stLine[ixEqual + 1:ixEqual + 10])
        stLine = f.readline()
    else:
        dFermi = None
    nKPt = int(stLine[32:36])
    listKPt = []
    listBand = []
    listB1 = []
    #    for i in xrange(0,nKPt):
    while True:
        stLine = f.readline()
        if not stLine:
            break
        stLine = stLine[:-1]  #Remove \cr for splitting
        if ("kpt" in stLine):
            listKPt.append([
                float(stLine[41:49]),
                float(stLine[49:57]),
                float(stLine[58:65]),
                float(stLine[26:35])
            ])
            if (len(listB1) > 0):
                listBand.append(listB1)
            listB1 = []
        else:
            #To avoid two maximum length float recognized as one
            #           listB1 += [float(x) if not "*" in x else 0.0 * energy_unit for x in stLine.split()]
            n = 10
            listB1 += [
                float(x) if not "*" in x else 0.0
                for x in [stLine[i:i + n] for i in xrange(0, len(stLine), n)]
            ]
    #Find band
    listBand.append(listB1)

    aKPt = KPointsT()
    aKPt.ReadFromList(listKPt)

    #   return aKPt, listBand, dFermi, None, 1
    return BandsT(aKPt, listBand, dFermi, None, None, 1)
Esempio n. 4
0
def abi_ReadBand_GW(stFileName):
    '''
    Read band structure from _GW file
    '''
    f = open(stFileName)
    nKPt, nSpin = [int(x) for x in f.readline().split()]
    listKPt = []
    listBand = []
    for i in xrange(0, nKPt):
        listKPt.append([float(x) for x in f.readline().split()])
        n = int(f.readline())
        listB = []
        for j in xrange(0, n):
            listB.append(float(f.readline().split()[1]))
        listBand.append(listB)

    aKPt = KPointsT()
    aKPt.ReadFromList(listKPt)

    #   return aKPt, listBand, None, None, nSpin
    return BandsT(aKPt, listBand, None, None, None, nSpin)
Esempio n. 5
0
def Main(ArgList):
    description = '''Plot band structure or DOS from data including kpoint-energy data, kpoint list, kpoint name list ( for band )  or energy-DOS data, PDOS name ( for DOS). Fermi energy can be used to adjust position in the process.
    %prog --fermi 0.5
'''
    usage = "%prog "
    parser = OptionParser(formatter=EmptyFormatter(),
                          usage=usage,
                          description=description)
    parser.add_option(
        "--band",
        dest="BandFileName",
        help=
        "Specify the energy data filename; This file should be a space or tabular split text file with all states in one k-points in one row"
    )
    parser.add_option(
        "--kpt",
        dest="KptFileName",
        help=
        "Specify the k-point list filename; This file should be a space or tabular split text file with x,y,z coordinate of k-vector in one line. The order must be the same as band file"
    )
    parser.add_option("--fermi",
                      dest="FermiFileName",
                      help="Specify the fermi energy filename.")
    parser.add_option(
        "-g",
        dest="Align",
        action="store_true",
        default=False,
        help=
        "If set to true, data will be modified to make E_F=0, otherwise a fermi level will be pointed out at its actual position"
    )
    parser.add_option(
        "--band2",
        dest="Band2FileName",
        default=None,
        help=
        "Specify the second energy data filename; the second energy data file will be plotted in dot mode"
    )
    parser.add_option("--fermi2",
                      dest="Fermi2FileName",
                      help="Specify the second fermi energy filename.")
    parser.add_option("--ymax",
                      dest="Ymax",
                      default=None,
                      help="Maximum of Y axis")
    parser.add_option("--ymin",
                      dest="Ymin",
                      default=None,
                      help="Minimum of Y axis")

    (options, args) = parser.parse_args(ArgList)

    if (len(args) != 1):
        parser.error("incorrect number of arguments.")

    #aKPT,list_band = f_ReadBandFile(options.stBandFileName,options.stKptFileName)
    list_band = f_Band_ReadFromFile(options.BandFileName)
    aKPT = KPointsT(options.KptFileName)

    if (options.Band2FileName != None):
        list_band2 = f_Band_ReadFromFile(options.Band2FileName)
    else:
        list_band2 = None

    eig_fermi = 0.0
    if (options.FermiFileName != None):
        eig_fermi = f_ReadFileFloatValue(options.FermiFileName)
        if (eig_fermi == None):
            print("Warning: fermi file not found, use 0.0 instead")
            eig_fermi = 0.0
    eig_fermi2 = 0.0
    if (options.Fermi2FileName != None):
        eig_fermi2 = f_ReadFileFloatValue(options.Fermi2FileName)
        if (eig_fermi == None):
            print("Warning: second fermi file not found, use 0.0 instead")
            eig_fermi2 = 0.0

    eig_max = None if options.Ymax == None else float(options.Ymax)
    eig_min = None if options.Ymin == None else float(options.Ymin)

    f_PlotBand(aKPT,
               list_band,
               eig_fermi,
               bAlignData=options.Align,
               list_band2=list_band2,
               eig_fermi2=eig_fermi2,
               y_min=eig_min,
               y_max=eig_max)
Esempio n. 6
0
def vasp_ReadBand(stFileName="EIGENVAL",filetype=None):
    '''
    Read k-point and band from vasp EIGENVAL file or OUTCAR file
    WARNING: EIGENVAL does not handle non-integer electrons! Use OUTCAR or vasprun.xml if it is that case
    Note the structure is always read from vasprun.xml

    Another problem is the occuptation numbers are 1 in vasprun.xml  and 2 in OUTCAR, if spin unpolarized

    :param stFileName: the file to read bandstructure
    :param filetype: the file type to read, can be OUTCAR or EIGENVAL. Automatically inferred from stFileName if set to None
    '''
    if (filetype is None):
        if ("EIGENVAL" in stFileName):
            filetype = "EIGENVAL"
        elif ("vasprun.xml" in stFileName):
            filetype = "vasprun.xml"
        else:
            filetype = "OUTCAR"

    f = open(stFileName)
    ar_stLine = f.readlines()
    f.close()

    list_kp = []
    list_band = []
    list_band2 = []
    list_occ = None
    bElectronFraction = False

    if (filetype == "EIGENVAL"):
#Note we cannot determine LNONCOLLINEAR in EIGENVAL, assume false
        b_noncoll = False

        num_spin = int(ar_stLine[0].split()[3])

        (nElectron,nKPt,nbnd) = [int(x) for x in ar_stLine[5].split()]

        for i in range(0,nKPt):
            i2 = i * (nbnd+2) + 7
            list_kp.append([float(x) for x in ar_stLine[i2].split()])
            ar2 =[x.split() for x in ar_stLine[i2+1:i2+nbnd+1]]
            list_band.append([float(x[1]) for x in ar2])
            if (num_spin == 2):
                list_band2.append([float(x[2]) for x in ar2])
        if (num_spin == 2):
            list_band = [list_band,list_band2]
    elif (filetype == "OUTCAR"):

        def read_tag(tag, i0):
            val = None
            for i in xrange(i0, len(ar_stLine)):
                line = ar_stLine[i]
                if (tag in line):
                    val = line.split()[2]
                    break
            if (val is None):
                raise ValueError("Cannot find tag %s" % tag)

            return val, i


        list_occ = []
        list_occ2 = []

        i = 0
        num_spin, i = read_tag("ISPIN", i)
        num_spin = int(num_spin)
        b_noncoll, i = read_tag("LNONCOLLINEAR", i)
        b_noncoll = b_noncoll == "T"
        nElectron, i = read_tag("NELECT", i)
        dElectron = float(nElectron)
        nElectron = int(dElectron)
        bElectronFraction = abs(dElectron != nElectron) > 1e-7
#       if (bElectronFraction):
#           print("The number of electrons is not an integer.")

        efermi, i = read_tag("E-fermi", i)
        efermi = float(efermi)
        i += 2
        if (num_spin != 1):
            i += 2
        list_band_now = list_band
        list_occ_now = list_occ
        while (len(ar_stLine[i+1])>4):
            i += 1
            if (list_band_now == list_band):
                list_kp.append([float(x) for x in ar_stLine[i].split()[-3:]])
            i += 2
            ar2 = []
            ar_occ = []
            line = ar_stLine[i]
            while (len(line) > 4):
                ar_line = line.split()
                ar2.append(float(ar_line[1]))
                ar_occ.append(float(ar_line[2]))
                i += 1
                line = ar_stLine[i]
            list_band_now.append(ar2)
            list_occ_now.append(ar_occ)
            if (num_spin != 1 and "spin" in ar_stLine[i+1]):
                list_band_now = list_band2
                list_occ_now = list_occ2
                i += 2

        nKPt = len(list_band)
        nbnd = len(list_band[0])
#       print(nElectron, nKPt, nbnd)
        if (num_spin == 2):
            list_band = [list_band, list_band2]
            list_occ = [list_occ, list_occ2]
    elif (filetype == "vasprun.xml"):
#Read from vasprun.xml
        for event, elem in ET.iterparse(stFileName,events=('end',)):
            if (elem.tag == "parameters"):
                node_parameters = elem
            elif (elem.tag == "eigenvalues"):
                node_eigenvalues = elem
            elif (elem.tag == "kpoints"):
                node_kpoints = elem
            elif (elem.tag == "dos"):
                node_dos = elem 
                break

#Read LNONCOLLINEAR
        b_noncoll = node_parameters.find('./separator[@name="electronic"]/separator[@name="electronic spin"]/i[@name="LNONCOLLINEAR"]').text
        b_noncoll = b_noncoll.strip() == "T"

#Read NELECT
        
        dElectron = float(node_parameters.find('./separator[@name="electronic"]/i[@name="NELECT"]').text)
        nElectron = int(dElectron)
        bElectronFraction = abs(dElectron != nElectron) > 1e-7

#Read band
        node_band = node_eigenvalues
        list_band = []
        list_occ = []
        list_occ2 = []
#3-level nested , hard to read so split them
        for node1 in node_band.findall("./array/set/set"): #Spin
            band_spin = []
            occ_spin = []
            for node2 in node1.findall("./set"): #Kpt
                data_kpt = [node3.text.split() for node3 in node2.findall("./r")]
                band_spin.append([float(x[0]) for x in data_kpt])
                occ_spin.append([float(x[1]) for x in data_kpt])
            list_band.append(band_spin)
            list_occ.append(occ_spin)
#       list_band = reduce(lambda x,y: x+y, list_band)
#       list_occ = reduce(lambda x,y: x+y, list_occ)
#Read kpoints coordinates
        list_kp = [[float(x) for x in nodek.text.split()] for nodek in node_kpoints.findall('./varray[@name="kpointlist"]/v')]

#Read other properties
        num_spin = int(node_parameters.find('./separator[@name="electronic"]/separator[@name="electronic spin"]/i[@name="ISPIN"]').text)
        efermi = float(node_dos.find('./i[@name="efermi"]').text)
#Do not use array for each spin if only 1 spin
        if (num_spin == 1):
            list_band = list_band[0]
            list_occ = list_occ[0]

    aKPT = KPointsT()
    aKPT.ReadFromList(list_kp)
    aKPT.stMode = "crystal"
    
    #OUTCAR is not necasseary, it is used to convert k-point unit
    try:
        latt = vasp_read_latt("initialpos","vasprun.xml")
    except ET.ParseError:
        matR,matK = vasp_ReadLattVec("OUTCAR")
        latt = Lattice()
        latt.ReadFromRawCellVector(matR)

    aKPT.latt = latt

#   aKPT.ConvertUnit("cart",matR)
    aKPT.ConvertUnit("cart")

#Each band is assumed to be double occupied in BandsT
#So we use 2 times electron in NONCOLLINEAR where only single occupied
    if (b_noncoll):
        print("Noncollinear calculation, band.electron = 2*actual electrons")
        nElectron *= 2 

    band = BandsT(aKPT,list_band,None,None,nElectron,num_spin, list_occ=list_occ)

    #Calculate VBM
#Only do if the number of electrons is an integer
    if (bElectronFraction):
        band.fermi = efermi
    else:
        if (not band.guess_vbm()):
            band.fermi = vasp_getout("efer")
    

#   return aKPT,list_band,dVBM,nElectron,1
    return band
Esempio n. 7
0
def yambo_read_band(filename, filename_pw_xml=None):
    '''
    Read band structure from yambo o-*.qp file
    Additional data-file.xml can be used to indicate information
    Lattice is a fake and not used
    '''
    with open(filename, 'r') as f:
        lines = f.readlines()

    ar = [[float(x) for x in line.split()] for line in lines if line[0] != "#"]
    for a1 in ar:
        a1[0] = int(a1[0])
        a1[1] = int(a1[1])
    ix_k = [x[0] for x in ar]
    ix_b = [x[1] for x in ar]
    ix_k_min = min(ix_k)
    ix_k_max = max(ix_k)
    ix_b_min = min(ix_b)
    ix_b_max = max(ix_b)

    #If spin=2, there is 6th column for spin
    #If not, only 5 columns
    if (len(ar[0]) == 5):
        num_spin = 1
    elif (len(ar[0]) == 6):
        num_spin = 2
    else:
        raise ValueError("Unknown number of columns %i" % len(ar[0]))

    if (filename_pw_xml is not None):
        band = qesp_read_band(filename_pw_xml)
        if (band.num_spin != num_spin):
            raise ValueError("Inconsistent spin for QE file and Yambo file")
        #Modify bands
#Set spin
        if (num_spin == 1):
            for a1 in ar:
                a1.append(0)
        else:
            for a1 in ar:
                a1[-1] = int((1 - a1[-1]) / 2)
#Set GW eigenvalues
#Note yambo make a shift to input DFT bands to make KS VBM=0,
#We shuold get it back
#Method 1 : calc shift and apply it to Yambo data
#       a = ar[0]
#       shift = a[2] - band.prop[a[-1]].eig[a[0]-1][a[1]-1]

#       for a in ar:
#           band.prop[a[-1]].eig[a[0]-1][a[1]-1] = a[2] + a[3] - shift

#Method 2 : add the correction to DFT instead of reading yambo DFT
        for a in ar:
            band.prop[a[-1]].eig[a[0] - 1][a[1] - 1] += a[3]

#Calculate properties
        if (band.vbm is not None):
            #Clear and recalculate
            band.vbm = None
            band.guess_vbm()

    else:
        if (num_spin == 1):
            list_eig = [[None] * (ix_b_max - ix_b_min + 1)
                        for x in range(ix_k_max - ix_k_min + 1)]
            for x in ar:  #Eo + (E-Eo)
                list_eig[x[0] - ix_k_min][x[1] - ix_b_min] = x[2] + x[3]
        elif (num_spin == 2):
            num_spin = 2
            list_eig = [[[None] * (ix_b_max - ix_b_min + 1)
                         for x in range(ix_k_max - ix_k_min + 1)],
                        [[None] * (ix_b_max - ix_b_min + 1)
                         for x in range(ix_k_max - ix_k_min + 1)]]
            for x in ar:  #Eo + (E-Eo)
                list_eig[int(
                    (1 - x[5]) / 2)][x[0] - ix_k_min][x[1] -
                                                      ix_b_min] = x[2] + x[3]

#Dummy kpt
        latt = Lattice()
        latt.ReadFromRawCellVector([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
        kpt = KPointsT()
        kpt.ReadFromList([[x, 0, 0] for x in range(len(list_eig))])
        kpt.unit = "crystal"
        kpt.latt = latt

        band = BandsT(kpt, list_eig, num_spin=num_spin)

    return band
Esempio n. 8
0
def wann_read_band(filename_band,
                   filename_kpt=None,
                   filename_gnu=None,
                   filename_out=None):
    '''
    Read band structure information from wannier90 output
    Indeed wannier90 output can be directly plotted but sometimes we need to combine two picture!
    :param filename_band: the name of eigenvalues ( normally seedname_band.dat )
    :param filename_kpt: the name of eigenvalues ( normally seedname_band.kpt;if not provided treated same as filename_band )
    :param filename_gnu: the name of gnuplot script ( if not provided treated same as band filename)
    :param filename_out: the name of stdout ( if not provided deduced from band filename)
    '''
    seedname = filename_band[:-9]
    if (filename_kpt == None):
        filename_kpt = seedname + "_band.kpt"
    if (filename_gnu == None):
        filename_gnu = seedname + "_band.gnu"
    if (filename_out == None):
        filename_out = seedname + ".wout"

    unit = wann_read_length_unit(filename_out)

    #K-points
    kpt1 = KPointsT()
    f = open(filename_kpt)
    n = int(f.readline())
    list_k = []
    for i in xrange(n):
        #Weight is ignored
        list_k.append([float(x) for x in f.readline().split()][0:3])
    f.close()
    kpt1.ReadFromList(list_k)
    #Bands
    list_band = f_Data_ReadTwoCol(filename_band)
    list_kcoord = [float(x[0]) for x in list_band]
    list_band = [[float(y) for y in x[1:]] for x in list_band]

    #Special k-points from gnuplot
    f = open(filename_gnu)
    for line in f:
        if ("xtics" in line):
            line2 = line[line.index("(") + 1:line.index(")")]
            ar = line2.split(",")
            for spec in ar:
                kcoord_last = 0.0
                kcoord_now = 0.0
                spec_name = spec[spec.index('"') + 1:spec.rindex('"')].strip()
                spec_value = float(spec[spec.rindex('"') + 1:])
                #               print(spec_name,spec_value)
                #Search nearest point
                for i, value in enumerate(list_kcoord):
                    #                   print(value)
                    if (spec_value <= value):  #
                        if (abs(spec_value - value) <=
                                abs(kcoord_last - spec_value)):
                            kpt1.listKPt[i][0] = spec_name
                        else:
                            kpt1.listKPt[i - 1][0] = spec_name
                        break
                    kcoord_last = value
                    #Detect the last one if not used
                    if (i == len(list_kcoord) - 1):
                        kpt1.listKPt[-1][0] = spec_name
#               print("Set kpt%i to %s" % ( i,spec_name))
            break
#Convert unit to Bohr
#However list_kcoord is not used later, maybe useful later
    if (unit == "Ang"):
        print("Convert unit from Angstrom to Bohr")
        list_kcoord = [x * Ang2Bohr for x in list_kcoord]

    return BandsT(kpt1, list_band, None, None, None, 1)