Beispiel #1
0
def band(phonon, start, end, npts, cartesian, output, branch, output_npy):
    "Given phonon data in IDF format, plot band structure along one direction"
    # phonon is the path to a directory with IDF phonon data

    # read phonon data
    from mccomponents.sample.phonon import periodicdispersion_fromidf as pd
    import mcni, numpy as np
    disp = pd(phonon)
    # and construct the proxy to the c++ data object
    import mccomponents.homogeneous_scatterer as mh
    cdisp = mh.scattererEngine(disp)
    # create Q array
    Qs = np.array(start) + (np.array(end) - np.array(start)) * np.arange(
        0, 1, 1. / npts)[:, np.newaxis]
    # Q will be cartesian
    if not cartesian:
        # read reciprocal basis vectors from Qgridinfo
        import os
        reci_basis = recibasis_fromQgridinfo(os.path.join(phonon, 'Qgridinfo'))
        Qs = np.dot(Qs, reci_basis)
    # compute energies
    nbr = disp.dispersion.nBranches
    Es = [cdisp.energy(br, mcni.vector3(*Q)) for Q in Qs for br in range(nbr)]
    Es = np.array(Es)
    Es.shape = -1, nbr
    # output
    if not output_npy:
        output_npy = 'bands-start%s-end%s.npy' % (start, end)
    np.save(output_npy, Es)
    try:
        import matplotlib as mpl
    except ImportError:
        import warnings
        warnings.warn(
            "Plotting needs matplotlib. Please install python matplotlib")
        return
    mpl.use("Agg")
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
    if branch == -1:
        for i in range(nbr):
            ax.plot(Es[:, i])
    else:
        ax.plot(Es[:, branch])
    if output:
        fig.savefig(output)
    else:
        plt.show()
    return
Beispiel #2
0
def band(phonon, start, end, npts, cartesian, output, branch):
    "Given phonon data in IDF format, plot band structure along one direction"
    # phonon is the path to a directory with IDF phonon data

    # read phonon data
    from mccomponents.sample.phonon import periodicdispersion_fromidf as pd
    import mcni, numpy as np
    disp = pd(phonon)
    # and construct the proxy to the c++ data object
    import mccomponents.homogeneous_scatterer as mh
    cdisp = mh.scattererEngine(disp)
    # create Q array
    Qs = np.array(start) + (np.array(end)-np.array(start)) * np.arange(0, 1, 1./npts)[:, np.newaxis]
    # Q will be cartesian
    if not cartesian:
        # read reciprocal basis vectors from Qgridinfo
        import os
        reci_basis = recibasis_fromQgridinfo(os.path.join(phonon, 'Qgridinfo'))
        Qs = np.dot(Qs, reci_basis)
    # compute energies
    nbr = disp.dispersion.nBranches
    Es = [cdisp.energy(br, mcni.vector3(*Q))
          for Q in Qs
          for br in range(nbr)]
    Es = np.array(Es)
    Es.shape = -1, nbr
    # output
    try:
        import matplotlib as mpl
    except ImportError:
        import warnings
        warnings.warn("Plotting needs matplotlib. Please install python matplotlib")
        return
    mpl.use("Agg")
    import matplotlib.pyplot as plt
    fig = plt.figure(); ax = fig.add_subplot(111)
    if branch == -1:
        for i in range(nbr):
            ax.plot(Es[:, i])
    else:
        ax.plot(Es[:, branch])
    if output:
        fig.savefig(output)
    else:
        plt.show()
    return
Beispiel #3
0
def slice(crystal, phonon, start, end, npts, cartesian, outhist, eaxis):
    "Given phonon data in IDF format, compute slice of SQE data along a specific reciprocal space direction"
    # phonon is the path to a directory with IDF phonon data

    # read phonon data
    from mccomponents.sample.phonon import periodicdispersion_fromidf as pd
    import mcni, numpy as np
    disp = pd(phonon)
    # and construct a proxy to the c++ data object
    import mccomponents.homogeneous_scatterer as mh
    cdisp = mh.scattererEngine(disp)
    # create Q array
    start = np.array(start)
    end = np.array(end)
    step = (end-start)/npts
    Qs = start + step * np.arange(0, npts, 1.)[:, np.newaxis]
    # Qs: cartesian, hkls: miller indexes
    import os
    reci_basis = recibasis_fromQgridinfo(os.path.join(phonon, 'Qgridinfo'))
    inv_reci_basis = np.linalg.inv(reci_basis)
    if cartesian:
        hkls = np.dot(Qs, inv_reci_basis)
        # these vectors will be used later in method Qtox
        start = np.dot(start, inv_reci_basis)
        step = np.dot(step, inv_reci_basis)
        end = np.dot(end, inv_reci_basis)
    else:
        hkls = Qs
        Qs = np.dot(hkls, reci_basis)
    # gather energies and polarizations
    nQ = len(Qs)
    nbr = disp.dispersion.nBranches
    natoms = disp.dispersion.nAtoms
    # energies
    Es = [cdisp.energy(br, mcni.vector3(*Q)) 
          for Q in Qs 
          for br in range(nbr)
          ]
    Es = np.array(Es)
    Es.shape = nQ, nbr
    # polarizations
    pols = [
        np.array(cdisp.polarization(br, atom, mcni.vector3(*Q)))
        for Q in Qs
        for br in range(nbr)
        for atom in range(natoms)
        ]
    pols = np.array(pols)
    pols.shape = nQ, nbr, natoms, 3

    # get atom positions from crystal structure file
    from danse.ins.matter.Parsers import getParser
    parser = getParser(os.path.splitext(crystal)[-1][1:])
    structure = parser.parseFile(crystal)
    atom_positions = [atom.xyz for atom in structure]
    # create "events" for later histogramming process to construct slice
    events = computeEvents(hkls, Es, pols, atom_positions, reci_basis)
    # for x axis of the histogram (along Q)
    maxx = np.linalg.norm(end-start)
    xaxis = 0, maxx, maxx/npts
    # Eaxis = 0, np.max(Es) * 1.1, 1.
    Eaxis = eaxis
    # functor to convert hkl to "x" value
    from distutils.version import LooseVersion
    def Qtox(hkl):
        if LooseVersion(np.__version__) >= LooseVersion("1.8"):
            x = np.linalg.norm(hkl-start, axis=-1)
        else:
            x = np.array(map(np.linalg.norm, hkl-start))
        mask = x==x
        return x, mask
    # histogramming
    h = makeSlice(events, xaxis, Eaxis, Qtox)
    # output
    import histogram.hdf as hh
    hh.dump(h, outhist)
    return
Beispiel #4
0
def slice(crystal, phonon, start, end, npts, cartesian, outhist, eaxis):
    "Given phonon data in IDF format, compute slice of SQE data along a specific reciprocal space direction"
    # phonon is the path to a directory with IDF phonon data

    # read phonon data
    from mccomponents.sample.phonon import periodicdispersion_fromidf as pd
    import mcni, numpy as np
    disp = pd(phonon)
    # and construct a proxy to the c++ data object
    import mccomponents.homogeneous_scatterer as mh
    cdisp = mh.scattererEngine(disp)
    # create Q array
    start = np.array(start)
    end = np.array(end)
    step = (end - start) / npts
    Qs = start + step * np.arange(0, npts, 1.)[:, np.newaxis]
    # Qs: cartesian, hkls: miller indexes
    import os
    reci_basis = recibasis_fromQgridinfo(os.path.join(phonon, 'Qgridinfo'))
    inv_reci_basis = np.linalg.inv(reci_basis)
    if cartesian:
        hkls = np.dot(Qs, inv_reci_basis)
        # these vectors will be used later in method Qtox
        start = np.dot(start, inv_reci_basis)
        step = np.dot(step, inv_reci_basis)
        end = np.dot(end, inv_reci_basis)
    else:
        hkls = Qs
        Qs = np.dot(hkls, reci_basis)
    # gather energies and polarizations
    nQ = len(Qs)
    nbr = disp.dispersion.nBranches
    natoms = disp.dispersion.nAtoms
    # energies
    Es = [cdisp.energy(br, mcni.vector3(*Q)) for Q in Qs for br in range(nbr)]
    Es = np.array(Es)
    Es.shape = nQ, nbr
    # polarizations
    pols = [
        np.array(cdisp.polarization(br, atom, mcni.vector3(*Q))) for Q in Qs
        for br in range(nbr) for atom in range(natoms)
    ]
    pols = np.array(pols)
    pols.shape = nQ, nbr, natoms, 3

    # get atom positions from crystal structure file
    from diffpy.Structure.Parsers import getParser
    parser = getParser(os.path.splitext(crystal)[-1][1:])
    structure = parser.parseFile(crystal)
    atom_positions = [atom.xyz for atom in structure]
    # create "events" for later histogramming process to construct slice
    events = computeEvents(hkls, Es, pols, atom_positions, reci_basis)
    # for x axis of the histogram (along Q)
    maxx = np.linalg.norm(end - start)
    xaxis = 0, maxx, maxx / npts
    # Eaxis = 0, np.max(Es) * 1.1, 1.
    Eaxis = eaxis
    # functor to convert hkl to "x" value
    from distutils.version import LooseVersion

    def Qtox(hkl):
        if LooseVersion(np.__version__) >= LooseVersion("1.8"):
            x = np.linalg.norm(hkl - start, axis=-1)
        else:
            x = np.array(map(np.linalg.norm, hkl - start))
        mask = x == x
        return x, mask

    # histogramming
    h = makeSlice(events, xaxis, Eaxis, Qtox)
    # output
    import histogram.hdf as hh
    hh.dump(h, outhist)
    return