Пример #1
0
def draw_dos(jobname, modes, custom_plotter=None, title=''):
    """Draw density of states with matplotlib in one subplot. """
    if custom_plotter is None:
        plotter = BandPlotter()
        callnextplot = False
    else:
        plotter = custom_plotter
        callnextplot = True

    for i, mode in enumerate(modes):
        fname = '{0}_{1}dos.csv'.format(jobname, mode)
        try:
            #freqs, dos = loadtxt(fname, delimiter=',', unpack=True)
            # genfromtxt does not throw an error if there is a '#.#':
            freqs, dos = np.genfromtxt(fname, delimiter=',', unpack=True)
        except IOError:
            log.error("in graphics.draw_dos: "
                      "File not found: {0}\n".format(fname) +
                      "Did you save DOS data in the simulation?")
            return plotter
        if callnextplot:
            callnextplot = False
            plotter.next_plot()

        plotter.plot_dos(dos, freqs)

    plotter.set_plot_title(title)

    return plotter
Пример #2
0
def draw_dos(jobname, modes, custom_plotter=None, title=''):
    """Draw density of states with matplotlib in one subplot. """
    if custom_plotter is None:
        plotter = BandPlotter()
        callnextplot = False
    else:
        plotter = custom_plotter
        callnextplot = True
    
    for i, mode in enumerate(modes):
        fname = '{0}_{1}dos.csv'.format(jobname, mode)
        try:
            #freqs, dos = loadtxt(fname, delimiter=',', unpack=True)
            # genfromtxt does not throw an error if there is a '#.#':
            freqs, dos = np.genfromtxt(fname, delimiter=',', unpack=True)
        except IOError:
            log.error("in graphics.draw_dos: "
                "File not found: {0}\n".format(fname) + 
                "Did you save DOS data in the simulation?")
            return plotter
        if callnextplot:
            callnextplot=False
            plotter.next_plot()
        
        plotter.plot_dos(dos, freqs)
            
    plotter.set_plot_title(title)
        
    return plotter
Пример #3
0
def draw_bands(jobname,
               modes,
               x_axis_hint=default_x_axis_hint,
               custom_plotter=None,
               title='',
               crop_y=True,
               band_gaps=True,
               light_cone=False,
               projected_bands=False,
               mask_proj_bands_above_light_line=False,
               add_epsilon_as_inset=False,
               color_by_parity=False,
               interactive_mode=False):
    """Plot dispersion relation of all bands calculated along all k
    vectors.

    :param jobname: The band data is loaded from previously saved .csv
    files. (filenames: [*jobname* + '_' + *mode* + 'freqs.csv' for mode
    in modes])
    :param modes: see *jobname*
    :param x_axis_hint: gives a hint on which kind of ticks and labels
    should be shown on the x-axis and provides the data needed.
    *x_axis_hint* can be one of the following:
        -- integer number:
            The axis' labels will be the 3D k-vectors. The number
            denotes the number of major ticks and labels distributed on
            the axis.
        -- [integer, format-string]:
            Same as above, but the labels are formatted with the
            format-string - this gives the possibility to only show one
            of the three vector components, e.g. the string "{2}" to
            only show the k-vector's z-component. The axis title will be
            inferred from the format-string.
        -- KSpace object:
            This must be a KSpace object created with point_labels.
            These labels usually denote the high symmetry or crititical
            points, and they will be shown on the axis.
        -- CustomAxisFormatter object:
            This gives the possibility to completely customize the
            x-axis' tick positions, tick labels and axis label. If the
            CustomAxisFormatter's hover data have not been set, it will
            be set here with the k-vectors read from the .csv file.

    :param custom_plotter: If you want to add the graph to an existing
    figure, supply a BandPlotter with *custom_plotter*, otherwise
    (default: custom_plotter=None) a new BandPlotter is created and
    returned.
    :param title: the subplot's title.
    :param crop_y: If this is true (default), the y-axis (frequency)
    will be limited so that only frequency values are shown where all
    bands are known. Alternatively, a numeric value of *crop_y* denotes
    the upper frequency value where the plot will be cropped, or if
    *crop_y* is a 2-tuple, it denotes the minimum and maximum y-value.
    :param band_gaps: If True, draw the band gaps (with colored boxes).
    :param light_cone: If True, add a light cone and crop the bandgaps
    at the light line. If the simulation was run on a substrate,
    light_cone must be the index of the refraction of this substrate.
    The light cone will then be scaled accordingly.
    :param projected_bands: If True, add bands that span a range of
    frequencies to the plot. Bandgaps are not drawn in this case. The
    data needed will be read from previously saved .csv files
    (filenames: [ jobname* + '_' + *mode* + '_projected.csv' for mode in
    modes]).
    :param mask_proj_bands_above_light_line: If *projected_bands* is
    True, some projected bands might be completely above the light line.
    These bands will not be drawn, if *mask_proj_bands_above_light_line*
    is True.
    :param add_epsilon_as_inset: epsilon,png will be added as inset. See
    defaults.py for parameters like size and location.
    :param color_by_parity: Specify 'y' or 'z' to color the plot lines
    with the data taken from the parity files
    <jobname>_<mode>[z/y]parity.csv.
    :param interactive_mode: This is useful if the plot is not intended for
    saving, but for showing on the screen. Then defaults.default_onclick()
    will be called if the user clicks on a graph in the figure.
    :return: a created BandPlotter instance (if *custom_plotter*) was
    None, or the *custom_plotter*.

    """
    if custom_plotter is None:
        plotter = BandPlotter(figure_size=defaults.fig_size)
    else:
        plotter = custom_plotter
        plotter.next_plot()

    refr_index = 1 if isinstance(light_cone, bool) else light_cone

    x_axis_formatter = None
    if isinstance(x_axis_hint, axis_formatter.CustomAxisFormatter):
        # use the supplied CustomAxisFormatter:
        x_axis_formatter = x_axis_hint
    elif isinstance(x_axis_hint, KSpace):
        # make a KSpaceAxisFormatter instance from kspace object:
        x_axis_formatter = axis_formatter.KSpaceAxisFormatter(x_axis_hint)
    elif isinstance(x_axis_hint, int):
        # make a standard KVectorAxisFormatter with supplied number of ticks:
        x_axis_formatter = axis_formatter.KVectorAxisFormatter(x_axis_hint)
    else:
        num = 0
        hintlen = 0
        if hasattr(x_axis_hint, '__len__'):
            hintlen = len(x_axis_hint)
        else:
            # no sequence
            try:
                # is this a number?
                num = int(x_axis_hint)
            except ValueError:
                # no number
                pass
        if hintlen > 1 and (isinstance(x_axis_hint[0], int)
                            and hasattr(x_axis_hint[1], 'format')):
            # Supplied a list with at least an int and format_str.
            # Use all items in list as KVectorAxisFormatter arguments:
            x_axis_formatter = axis_formatter.KVectorAxisFormatter(
                *x_axis_hint)
        elif num > 0:
            # make a standard KVectorAxisFormatter with supplied number
            # of ticks:
            x_axis_formatter = axis_formatter.KVectorAxisFormatter(num)
    if x_axis_formatter is None:
        log.warning('draw_bands: Did not understand x_axis_hint, '
                    'using default.')
        x_axis_formatter = axis_formatter.KVectorAxisFormatter(
            default_x_axis_hint)

    for i, mode in enumerate(modes):
        fname = '{0}_{1}freqs.csv'.format(jobname, mode)
        data = loadtxt(fname, delimiter=',', skiprows=1)

        # add hover data:
        if x_axis_formatter._hover_func_is_default:
            x_axis_formatter.set_hover_data(data[:, 1:4])

        parities = None
        if color_by_parity:
            # try to load parity file:
            fname = '{0}_{1}{2}parity.csv'.format(jobname, mode,
                                                  color_by_parity)
            try:
                # load data, ignore first column with band numbers:
                parities = loadtxt(fname, delimiter=',')[:, 1:]
            except IOError:
                parities = None

        plotter.plot_bands(data[:, 5:],
                           data[:, 1:5],
                           formatstr=defaults.draw_bands_formatstr,
                           x_axis_formatter=x_axis_formatter,
                           label=mode.upper(),
                           crop_y=crop_y,
                           picker=interactive_mode * 3,
                           color_by_parity=parities,
                           **defaults.draw_bands_kwargs)

        if projected_bands:
            fname = '{0}_{1}_projected.csv'.format(jobname, mode)
            with np.warnings.catch_warnings():
                # ignore numpy warning if the file does not contain any
                # data, just return empty ndarray:
                np.warnings.simplefilter("ignore")
                projdata = loadtxt(fname, delimiter=',', ndmin=2)
            if projdata.shape[0] != 0:
                if projdata.shape[1] % 2 != 0:
                    # knums added in first column, drop it:
                    projdata = projdata[:, 1:]

                if light_cone and mask_proj_bands_above_light_line:
                    # ignore projected bands above the light line:
                    mask = np.zeros_like(projdata, dtype=np.bool)
                    numbands = projdata.shape[1] // 2
                    for i in range(numbands):
                        if (projdata[:, 2 * i] >
                                data[:, 4] / refr_index).all():
                            mask[:, 2 * i:2 * i + 2] = True
                    projdata = np.ma.array(projdata, mask=mask)

                if projdata.shape[0] == 1 and data.shape[0] != 1:
                    # the same band ranges for all k-vecs:
                    newproj = np.empty((data.shape[0], projdata.shape[1]))
                    newproj[None, :] = projdata
                    projdata = newproj

                plotter.add_continuum_bands(projdata)
        if band_gaps:
            if light_cone:
                gapbands = get_gap_bands(data[:, 5:],
                                         light_line=data[:, 4] / refr_index)
            else:
                gapbands = get_gap_bands(data[:, 5:])
            for band in gapbands:
                plotter.add_band_gap_rectangle(
                    band[1],
                    band[2],
                    light_line=data[:, 4] / refr_index if light_cone else None)

    if light_cone:
        plotter.add_light_cone(refr_index)

    plotter.set_plot_title(title)

    if len(modes) > 1 or (len(modes) == 1 and modes[0] != ''):
        plotter.add_legend()

    if color_by_parity:
        plotter.add_color_bar_for_parity(parity_direction=color_by_parity)

    if add_epsilon_as_inset:
        fname = path.join(path.split(jobname)[0], 'epsilon.png')
        if path.isfile(fname):
            plotter.add_image_inset(fname,
                                    loc=defaults.epsilon_inset_location,
                                    zoom=defaults.epsilon_inset_zoom,
                                    transpose=defaults.epsilon_inset_transpose)

    return plotter
Пример #4
0
def draw_bands(
        jobname, modes, x_axis_hint=default_x_axis_hint,
        custom_plotter=None, title='', crop_y=True,
        band_gaps=True, light_cone=False, projected_bands=False,
        mask_proj_bands_above_light_line=False,
        add_epsilon_as_inset=False, color_by_parity=False,
        interactive_mode=False):
    """Plot dispersion relation of all bands calculated along all k
    vectors.

    :param jobname: The band data is loaded from previously saved .csv
    files. (filenames: [*jobname* + '_' + *mode* + 'freqs.csv' for mode
    in modes])
    :param modes: see *jobname*
    :param x_axis_hint: gives a hint on which kind of ticks and labels
    should be shown on the x-axis and provides the data needed.
    *x_axis_hint* can be one of the following:
        -- integer number:
            The axis' labels will be the 3D k-vectors. The number
            denotes the number of major ticks and labels distributed on
            the axis.
        -- [integer, format-string]:
            Same as above, but the labels are formatted with the
            format-string - this gives the possibility to only show one
            of the three vector components, e.g. the string "{2}" to
            only show the k-vector's z-component. The axis title will be
            inferred from the format-string.
        -- KSpace object:
            This must be a KSpace object created with point_labels.
            These labels usually denote the high symmetry or crititical
            points, and they will be shown on the axis.
        -- CustomAxisFormatter object:
            This gives the possibility to completely customize the
            x-axis' tick positions, tick labels and axis label. If the
            CustomAxisFormatter's hover data have not been set, it will
            be set here with the k-vectors read from the .csv file.

    :param custom_plotter: If you want to add the graph to an existing
    figure, supply a BandPlotter with *custom_plotter*, otherwise
    (default: custom_plotter=None) a new BandPlotter is created and
    returned.
    :param title: the subplot's title.
    :param crop_y: If this is true (default), the y-axis (frequency)
    will be limited so that only frequency values are shown where all
    bands are known. Alternatively, a numeric value of *crop_y* denotes
    the upper frequency value where the plot will be cropped, or if
    *crop_y* is a 2-tuple, it denotes the minimum and maximum y-value.
    :param band_gaps: If True, draw the band gaps (with colored boxes).
    :param light_cone: If True, add a light cone and crop the bandgaps
    at the light line. If the simulation was run on a substrate,
    light_cone must be the index of the refraction of this substrate.
    The light cone will then be scaled accordingly.
    :param projected_bands: If True, add bands that span a range of
    frequencies to the plot. Bandgaps are not drawn in this case. The
    data needed will be read from previously saved .csv files
    (filenames: [ jobname* + '_' + *mode* + '_projected.csv' for mode in
    modes]).
    :param mask_proj_bands_above_light_line: If *projected_bands* is
    True, some projected bands might be completely above the light line.
    These bands will not be drawn, if *mask_proj_bands_above_light_line*
    is True.
    :param add_epsilon_as_inset: epsilon,png will be added as inset. See
    defaults.py for parameters like size and location.
    :param color_by_parity: Specify 'y' or 'z' to color the plot lines
    with the data taken from the parity files
    <jobname>_<mode>[z/y]parity.csv.
    :param interactive_mode: This is useful if the plot is not intended for
    saving, but for showing on the screen. Then defaults.default_onclick()
    will be called if the user clicks on a graph in the figure.
    :return: a created BandPlotter instance (if *custom_plotter*) was
    None, or the *custom_plotter*.

    """
    if custom_plotter is None:
        plotter = BandPlotter(figure_size=defaults.fig_size)
    else:
        plotter = custom_plotter
        plotter.next_plot()

    refr_index = 1 if isinstance(light_cone, bool) else light_cone

    x_axis_formatter = None
    if isinstance(x_axis_hint, axis_formatter.CustomAxisFormatter):
        # use the supplied CustomAxisFormatter:
        x_axis_formatter = x_axis_hint
    elif isinstance(x_axis_hint, KSpace):
        # make a KSpaceAxisFormatter instance from kspace object:
        x_axis_formatter = axis_formatter.KSpaceAxisFormatter(x_axis_hint)
    elif isinstance(x_axis_hint, int):
        # make a standard KVectorAxisFormatter with supplied number of ticks:
        x_axis_formatter = axis_formatter.KVectorAxisFormatter(x_axis_hint)
    else:
        num = 0
        hintlen = 0
        if hasattr(x_axis_hint, '__len__'):
            hintlen = len(x_axis_hint)
        else:
            # no sequence
            try:
                # is this a number?
                num = int(x_axis_hint)
            except ValueError:
                # no number
                pass
        if hintlen > 1 and (isinstance(x_axis_hint[0], int) and
                hasattr(x_axis_hint[1], 'format')):
            # Supplied a list with at least an int and format_str.
            # Use all items in list as KVectorAxisFormatter arguments:
            x_axis_formatter = axis_formatter.KVectorAxisFormatter(
                *x_axis_hint)
        elif num > 0:
            # make a standard KVectorAxisFormatter with supplied number
            # of ticks:
            x_axis_formatter = axis_formatter.KVectorAxisFormatter(num)
    if x_axis_formatter is None:
        log.warning('draw_bands: Did not understand x_axis_hint, '
            'using default.')
        x_axis_formatter = axis_formatter.KVectorAxisFormatter(
            default_x_axis_hint)

    for i, mode in enumerate(modes):
        fname = '{0}_{1}freqs.csv'.format(jobname, mode)
        data = loadtxt(fname, delimiter=',', skiprows=1)

        # add hover data:
        if x_axis_formatter._hover_func_is_default:
            x_axis_formatter.set_hover_data(data[:, 1:4])

        parities = None
        if color_by_parity:
            # try to load parity file:
            fname = '{0}_{1}{2}parity.csv'.format(
                jobname, mode, color_by_parity)
            try:
                # load data, ignore first column with band numbers:
                parities = loadtxt(fname, delimiter=',')[:, 1:]
            except IOError:
                parities = None

        plotter.plot_bands(
            data[:, 5:], data[:, 1:5],
            formatstr=defaults.draw_bands_formatstr,
            x_axis_formatter=x_axis_formatter,
            label=mode.upper(),
            crop_y=crop_y,
            picker = interactive_mode * 3,
            color_by_parity=parities,
            **defaults.draw_bands_kwargs)

        if projected_bands:
            fname = '{0}_{1}_projected.csv'.format(jobname, mode)
            with np.warnings.catch_warnings():
                # ignore numpy warning if the file does not contain any
                # data, just return empty ndarray:
                np.warnings.simplefilter("ignore")
                projdata = loadtxt(fname, delimiter=',', ndmin=2)
            if projdata.shape[0] != 0:
                if projdata.shape[1] % 2 != 0:
                    # knums added in first column, drop it:
                    projdata = projdata[:, 1:]

                if light_cone and mask_proj_bands_above_light_line:
                    # ignore projected bands above the light line:
                    mask = np.zeros_like(projdata, dtype=np.bool)
                    numbands = projdata.shape[1] // 2
                    for i in range(numbands):
                        if (projdata[:, 2 * i] >
                                    data[:, 4] / refr_index).all():
                            mask[:, 2 * i:2 * i + 2] = True
                    projdata = np.ma.array(projdata, mask=mask)

                if projdata.shape[0] == 1 and data.shape[0] != 1:
                    # the same band ranges for all k-vecs:
                    newproj = np.empty((data.shape[0], projdata.shape[1]))
                    newproj[None, :] = projdata
                    projdata = newproj

                plotter.add_continuum_bands(projdata)
        if band_gaps:
            if light_cone:
                gapbands = get_gap_bands(
                    data[:, 5:], light_line=data[:, 4] / refr_index)
            else:
                gapbands = get_gap_bands(data[:, 5:])
            for band in gapbands:
                bsize = 2 * (band[2] - band[1]) / (band[2] + band[1])
                if bsize >= defaults.min_gapsize:
                    plotter.add_band_gap_rectangle(
                        band[1], band[2],
                        light_line= \
                            data[:,4] / refr_index if light_cone else None)

    if light_cone:
        plotter.add_light_cone(refr_index)

    plotter.set_plot_title(title)

    if len(modes) > 1 or (len(modes) == 1 and modes[0]!=''):
        plotter.add_legend()

    if color_by_parity:
        plotter.add_color_bar_for_parity(parity_direction=color_by_parity)

    if add_epsilon_as_inset:
        fname = path.join(path.split(jobname)[0], 'epsilon.png')
        if path.isfile(fname):
            plotter.add_image_inset(
                fname,
                loc=defaults.epsilon_inset_location,
                zoom=defaults.epsilon_inset_zoom,
                transpose=defaults.epsilon_inset_transpose
            )

    return plotter