Exemplo n.º 1
0
def uni_ReadPDOS(stProgram="auto",para=[]):
    '''
    Read DOS from specific program result
    :param stProgram: program name, "auto" means automatically detected
    :return:  names of states, energy points, DOS,VBM
    '''
    stProgram = uni_Package_Detect(stProgram,para)

#    dicFunc = {"auto":[0,None],"w2k":[0,w2k_ReadBand],"yaeh":[1,yaeh_ReadBand],"siesta":[3,siesta_ReadBand],"vasp":[0,vasp_ReadBand],"qe":[1,QESP_ReadBand]}
    dicFunc = {"auto":[0,None],"siesta":[1,siesta_read_pdos],"vasp":[0,vasp_ReadPDOS],"qe":[1,QESP_ReadPDOS],"w2k":[0,w2k_ReadPDOS]}

    if ( not dicFunc.has_key(stProgram) ):
        raise ValueError,"Package %s is not supported!" % stProgram

    if ( len(para)  != dicFunc[stProgram][0]):
        raise ValueError,"incorrect number of arguments."
    
    #(aKPt,listBand,dVBM) = dicFunc[stProgram][1](*para)
    return  dicFunc[stProgram][1](*para)
Exemplo n.º 2
0
def uni_read_band_character(stProgram="auto", para=[]):
    '''
    Read band character informations

    :return: two lists, first is list of components in OrbitalT, second is [kpt,band] nested array of all components
    '''
    stProgram = uni_Package_Detect(stProgram, para)

    dicFunc = {
        "auto": [(0, ), None],
        "w2k": [(0, ), w2k_read_band_character],
        "vasp": [(0, ), vasp_read_band_character]
    }

    if (not dicFunc.has_key(stProgram)):
        raise ValueError, "Package %s is not supported!" % stProgram

    if (not len(para) in dicFunc[stProgram][0]):
        raise ValueError, "incorrect number of arguments."

    return dicFunc[stProgram][1](*para)
Exemplo n.º 3
0
def uni_ReadBand(stProgram="auto", para=[]):
    '''
    Read band structure from specific program result
    :param stProgram: program name, "auto" means automatically detected
    :param para: arguments for specific programs
    :return: BandsT object
    '''
    #   :param nElectron: electron number, default 0. If specified, then VBM will be calculated for plot
    #   :param bPlot: Whether plot bandstructure
    #   :param bAlign: Whether shift band energy to make VBM = 0 in plot
    #    :return:  k-points,eigenvalues,VBM,Electron count,Spin count
    #    '''

    stProgram = uni_Package_Detect(stProgram, para)

    dicFunc = {\
            "auto":[(0,),None],\
            "w2k":[(0,1,),w2k_ReadBand],\
            "yaeh":[(1,),yaeh_ReadBand],\
            "siesta":[(3,),siesta_read_band],\
            "vasp":[(0,),vasp_ReadBand],\
            "vasp_out":[(1,),vasp_ReadBand],\
            "qe":[(1,), qesp_read_band],\
            "abinit":[(2,),abi_ReadBand],\
            "gap":[(1,),w2k_ReadBand],\
            "w90":[(1,),wann_read_band],\
            "bdf":[(1,),bdf_read_band],\
            "yambo":[(1,2,),yambo_read_band],\
            "raw":[(1,),lambda x:BandsT(dirname=x)],\
            "band":[(1,),read_eigs]\
            }

    if (not dicFunc.has_key(stProgram)):
        raise ValueError, "Package %s is not supported!" % stProgram

    if (not len(para) in dicFunc[stProgram][0]):
        raise ValueError, "incorrect number of arguments : %i" % len(para)

    #(aKPt,listBand,dVBM) = dicFunc[stProgram][1](*para)
    return dicFunc[stProgram][1](*para)
Exemplo n.º 4
0
def Main(ArgList):
    description = '''Plot band strcture of specific package in specific format, also create plain tabular seperated text of band structure data and k-points list.
    File required:
        SIESTA : .fdf , stdout, .bands
        VASP : none, require to run in the case folder
        WIEN2K :  none , require to run in the case folder
        FHI-GAP : energy file name suffix (_gw-band or _gw0-band) , require to run in the WIEN2k case folder
        QE : data-file.xml in the save folder, or pw.x output
        ABINIT : _EIG output or _GW output
        Wannier90: _w90_band.dat file ( other files are necessary but will be selected according to this file name)
        Yambo : o-*.qp file
        RAW: folder name contains all files generated by %prog 
    By default, output folder is current folder, so it is sugguested to run this in an empty folder to avoid overwritten as it will create plenty of files.
    Band characteres can also be plotted. To do this add "--plotinfo File". The input file contains extra format informations.
    '''
    parser = ArgumentParser(description=description,
                            formatter_class=RawDescriptionHelpFormatter)

    parser.add_argument("extra_args",
                        type=str,
                        nargs="*",
                        help="Arguments passed to package-specific procedures")
    parser.add_argument("-i",
                        dest="Program",
                        default="auto",
                        help="The package name")
    parser.add_argument("-g",
                        dest="Align",
                        default=False,
                        action="store_true",
                        help="Shift band position to make VBM = 0 in graph")
    parser.add_argument(
        "--electron",
        dest="Electron",
        default="0",
        help=
        "The number of electrons in the system of the band structure. This is used to determine VBM/Fermi energy. If not specified, this program will try to find from input files"
    )
    parser.add_argument(
        "-s",
        dest="FormatOnly",
        default=False,
        action="store_true",
        help=
        "Do not plot band structure, just write band structure data and k-point list in space-seperated format"
    )
    parser.add_argument("-d",
                        dest="OutputDir",
                        default="band",
                        help="The name of folder used to store output files")
    parser.add_argument(
        "-k",
        dest="KPointsUnit",
        default="cart",
        help=
        "The unit of k-points in the output, also determine x-axis distance. Possible options include 'cart','crystal' and 'default', where default means use what the program read."
    )
    parser.add_argument(
        "-f",
        dest="ForceOverwrite",
        default=False,
        action="store_true",
        help=
        "Control whether to overwrite if the output directory already exists, default is not "
    )
    parser.add_argument(
        "--cross",
        dest="ResolveCorssing",
        default=False,
        action="store_true",
        help="Contrl whether to resolving band-crossing by derivatives")
    parser.add_argument(
        "--plotinfo",
        dest="FilePlotInfo",
        default=None,
        help=
        "The input file for plotting parameters, include band structure with band characters indicated"
    )
    parser.add_argument(
        "--copyk",
        dest="CopyKPoints",
        default=None,
        help=
        "Copy k-points information from given band.xml, instead of use what is read. This to make two plots have the same x-coord"
    )
    parser.add_argument(
        "--removek",
        dest="RemoveKPoints",
        type=int,
        default=0,
        help=
        "Remove the first N k-points in the bandstructure, especially useful when plotting HSE / metaGGA bands that must be calculated with full M-P k-points self-consistently"
    )
    parser.add_argument(
        "--kname",
        dest="NameK",
        default=None,
        help=
        "Provide a list of names of k-points that will be plotted, in format \" 1 Gamma 30 X 50 L\", indicies start from 1, this works before --removek"
    )
    parser.add_argument(
        "--alignenergy",
        dest="AlignEnergy",
        default=None,
        help=
        "Manually specify the energy to align instead of using VBM/Fermi energy automatically read. The unit must be the same as what the package outputs."
    )

    options = parser.parse_args()

    stProgram = uni_Package_Detect(options.Program, options.extra_args)
    band = uni_ReadBand(stProgram, options.extra_args)
    #Read k-points
    if (options.CopyKPoints is not None):
        band_copyk = BandsT.load_xml(options.CopyKPoints)
        band.kpt = band_copyk.kpt

    if (options.NameK is not None):
        list_name = options.NameK.split()
        for i in xrange(len(list_name) / 2):
            ix1 = int(list_name[i * 2]) - 1
            name1 = list_name[i * 2 + 1]
            band.kpt.listKPt[ix1][0] = name1

#Read character informations
    info_plot = None
    if (options.FilePlotInfo is not None):
        with open(options.FilePlotInfo) as f:
            info_plot = json.loads(f.read())
        if (info_plot.has_key("orb_map")):
            list_orb, list_character = uni_read_band_character(stProgram)
            if (stProgram == "w2k"):  #Wien2K qtl is not good for plotting
                list_character = w2k_rescale_character(band.list_orb,
                                                       band.list_character)
#Add to band object
            for prop, orb, character in zip(band.prop, list_orb,
                                            list_character):
                prop.orb = orb
                prop.character = character

#Remove extra k-points
    if (options.RemoveKPoints > 0):
        band = f_band_remove_k(band, options.RemoveKPoints)

#Resolving crossing
    if (options.ResolveCorssing):
        band.resolve_crossing()

#Unit conversion
    unit_k = options.KPointsUnit.lower()
    if (unit_k != "default" and band.kpt.stMode != unit_k):
        print("Convert k-point unit from %s to %s" % (band.kpt.stMode, unit_k))
        #band.kpt.ConvertUnit(unit_k,band.kpt.latt.PrimitiveCellVector)
        band.kpt.ConvertUnit(unit_k)

    nElectronInput = int(options.Electron)
    if (nElectronInput != 0):
        band.num_electron = nElectronInput

#Align energy
    if (options.AlignEnergy is not None):
        e1 = float(options.AlignEnergy)
        band.fermi = e1
        band.vbm = e1


#   f_Band_Analyse(listBand)
    band.show_info((
        band.fermi if band.b_metal else band.vbm) if options.Align else None)

    #   f_Band_SaveData(aKPt,listBand,dVBM,options.OutputDir,nElectron,not options.FormatOnly,options.Align)
    if (os.path.exists(options.OutputDir) and not options.ForceOverwrite):
        print(
            "Warning:Directory %s already exists, band structure information will not be saved!"
            % options.OutputDir)
        return

    band.save(options.OutputDir,
              b_plot=not options.FormatOnly,
              align=BandsT.align_auto if options.Align else BandsT.align_none,
              plotinfo=info_plot)
Exemplo n.º 5
0
def Main(ArgList):
    description = '''Plot DOS of specific package in specific format, also create one-file plain tabular seperated text for DOS.
    File required:
        SIESTA :  pdos.xml or $CASE$.PDOS
        VASP : none, require to run in the case folder
        WIEN2K :  none , require to run in the case folder
        QE :  prefix of output filenames, require to run in the folder contains all output of projwfc.x
    By default, output folder is current folder, so it is sugguested to run this with -d option to redirect output files to another folder as it will create plenty of files.
    Example:
    py_dos.py -d dos --format "%s%i(%l)(%spin)" --filter "x.species=='O'"
    '''
    usage = "%prog -i PROGRAM [program related parameters like $CASE.fdf $CASE.bands] [-g] [-s] [-d OutputFolder] -c [Combine] --filter [Filter]"
    
    parser = ArgumentParser(description=description, formatter_class=RawDescriptionHelpFormatter)

    parser.add_argument("extra_args", type=str, nargs="*", help="Arguments passed to package-specific procedures")
    parser.add_argument("-i",dest="Program",default="auto",help="The package name")
    parser.add_argument("-g",dest="Align",default=False,action="store_true",help="Shift band position to make VBM = 0 in graph")
    parser.add_argument("-s",dest="FormatOnly",default=False,action="store_true",help="Do not plot band structure, just write band structure data and k-point list in space-seperated format")
    parser.add_argument("-d",dest="OutputDir",default="dos",help="The name of folder used to store output files")
    parser.add_argument("-f",dest="ForceOverwrite",default=False,action="store_true",help="Control whether to overwrite if the output directory already exists, default is not ")
    parser.add_argument("--format",dest="Format",default="z",help="Combine multiple DOS into a single one in specific level. Levels include %%spin,%%m,%%l,%%n,%%i(atom index),%%s(species),%%t(total)." + \
    " This string also indicates display names, format strings like %%x will be replaced while others will be kept")
    parser.add_argument("--filter",dest="Filter",default=None,help="The command to judge whether a specific orbital should be included in final results, like 'x.l ==1 and x.i < 70'. Warning: This string will be EXECCUTED DIRECTLY so be cautious!")
    parser.add_argument("--plotinfo", dest="FilePlotInfo", default=None, help="The input file for plotting parameters")

    options = parser.parse_args()

    stProgram = uni_Package_Detect(options.Program, options.extra_args)
    print("Reading PDOS...")
    listName,listEnergy,listDOS,dVBM = uni_ReadPDOS(stProgram, options.extra_args)
    print("Read PDOS OK...")
    print("Parsing PDOS ...")
    listName,listDOS=f_DOS_SortPDOS(listName,listDOS)


#Read plotinfo
    info_plot = None
    if (options.FilePlotInfo is not None):
        with open(options.FilePlotInfo) as f:
            info_plot = json.loads(f.read())

    
#Filter
    if (options.Filter != None):
        list = zip(listName,listDOS)
        list = [x for x in list if f_pdos_filter(x[0],options.Filter)]
        if (len(list) ==0):
            print("All orbitals are filtered! Nothing will be printed.")
            sys.exit(0)
        (listName,listDOS) = zip(*list)
#Combine
#Old-style
#    if ( options.CombineLevel != "z"):
#        listName,listDOS = f_DOS_CombinePDOS(listName,listDOS,options.CombineLevel)
#New-style
#Extract indicators from Format
    b_split_spin = "%spin" in options.Format
    st = options.Format
    list_mark = []
    if (b_split_spin):
        list_mark.append("spin")
        st = st.replace("%spin","")
    i2 = 0
    while (True):
        i2 = st.find("%",i2)
        if (i2 == -1):
            break
        list_mark.append(st[i2+1])
        i2 += 1
    
    func_same = f_pdos_combine(list_mark)
    listName,listDOS = f_DOS_CombinePDOS(listName,listDOS,func_same=func_same)
#Debug line
#   for name in listName:
#       print(name.ToString("z"))

#Reverse spin-down data to negative
    if (b_split_spin):
        print("Note: spin-down data are stored as negative values")
        list = zip(listName,listDOS)
        list = [[x[0],[-y for y in x[1]] if x[0].spin == -1 else x[1]]  for x in list]
        (listName,listDOS) = zip(*list)

        #Convert name
#Create name string
#   listName = [ OrbitalNameT.ToString(x,options.CombineLevel) for x in listName]
    listName = [ OrbitalNameT.ToStringFormat(x,options.Format) for x in listName]

    #Save data
    if (os.path.exists(options.OutputDir) and not options.ForceOverwrite):
        print("Warning:Directory %s already exists, band structure information will not be saved!" % options.OutputDir)
        return

    f_DOS_SaveData(listName,listEnergy,listDOS,dVBM,options.OutputDir,not options.FormatOnly,options.Align, info_plot)