Ejemplo n.º 1
0
def plot_ima_spectra(
    start,
    finish,
    species=["H", "O", "O2"],
    colorbar=True,
    ax=None,
    blocks=None,
    check_times=True,
    return_val=None,
    verbose=False,
    check_overlap=True,
    vmin=2,
    vmax=7.0,
    raise_all_errors=False,
    cmap=None,
    norm=None,
    die_on_empty_blocks=False,
    accept_new_tables=True,
    inverted=True,
    **kwargs
):

    """ Plot IMA spectra from start - finish, .
    blocks is a list of data blocks to work from, if this is not specified then we'll read them
    species names: [only those with x will function]
        heavy (16, 85, 272) x
        sumions (85, 32)
        CO2 (16, 85, 272) x
        E (96, 1)
        Horig (16, 85, 272) x
        tmptime (1, 272)
        H (16, 85, 272)
        dE (1, 85)
        sumorigions (85, 32)
        O (16, 85, 272) x
        Hsp (16, 85, 272) x
        mass (50, 272)
        alpha (16, 85, 272) x
        O2 (16, 85, 272) x
        He (16, 85, 272) x

    for blocks read with dataset='fion', we'll add an 'f' before
            CO2, O2, O2plus, O, Horig, He, H
    automagically
    """

    if not blocks:
        blocks = read_ima(start, finish, verbose=verbose, **kwargs)

    if ax is None:
        ax = plt.gca()
    plt.sca(ax)
    ax.set_axis_bgcolor("lightgrey")

    if not cmap:
        cmap = matplotlib.cm.Greys_r
        # cmap.set_under('white')
    if not norm:
        norm = plt.Normalize(vmin, vmax, clip=True)

    ims = []

    last_finish = -9e99

    if blocks:
        if "fH" in list(blocks[0].keys()):  # blocks were read with dataset='fion'
            if isinstance(species, str):
                if species in ("O", "H", "He", "alpha", "Horig", "O2", "O2plus", "CO2"):
                    species = "f" + species
            else:
                new_species = []
                for s in species:
                    if s in ("O", "H", "He", "alpha", "Horig", "O2", "O2plus", "CO2"):
                        new_species.append("f" + s)
                species = new_species

    # if isinstance(species, basestring):
    #     if species[0] == 'f':
    #         label =  species[1:] + r' flux \n / $cm^{-2}s^{-1}$'
    #     else:
    #         label = species + '****'
    # else:
    #     label = ''
    #     for s in species:
    #         if s[0] == 'f':
    #             label += s[1:] + ', '
    #         else:
    #             label += s
    #     label += r' flux \n/ $cm^{-2}s^{-1}$'

    label = r"Flux / $cm^{-2}s^{-1}$"

    # Make sure we set the ylimits correctly by tracking min and max energies
    min_energy = 60000.0
    max_energy = -10.0

    for b in blocks:
        # min(abs()) to account for negative values in E table
        extent = [
            celsius.matlabtime_to_spiceet(b["tmptime"][0]),
            celsius.matlabtime_to_spiceet(b["tmptime"][-1]),
            min(abs(b["E"])),
            max(b["E"]),
        ]
        # Account for the varying size of the Energy table:
        if b["sumions"].shape[0] == 96:
            extent[2] = b["E"][-1]
            extent[3] = b["E"][0]
        elif b["sumions"].shape[0] == 85:  # revised energy table
            extent[2] = b["E"][-11]
            extent[3] = b["E"][0]
            if extent[2] < 0.0:
                raise ValueError("Energies should be positive - unrecognised energy table?")
        else:
            if accept_new_tables:
                extent[2] = np.min(np.abs(b["E"]))
                extent[3] = b["E"][0]
                print("New table:", extent[2], extent[3], b["E"][-1], b["E"][0], b["sumions"].shape[0])
            else:
                raise ValueError(
                    "Unrecognised energy table: E: %e - %e in %d steps?"
                    % (b["E"][-1], b["E"][-1], b["sumions"].shape[0])
                )

        if extent[2] < min_energy:
            min_energy = extent[2]

        if extent[3] > max_energy:
            max_energy = extent[3]

        if check_times:
            spacing = 86400.0 * np.mean(np.diff(b["tmptime"]))
            if spacing > 15.0:
                if raise_all_errors:
                    raise ValueError("Resolution not good? Mean spacing = %fs " % spacing)
                else:
                    plt.annotate(
                        "Resolution warning:\nmean spacing = %.2fs @ %s "
                        % (spacing, celsius.utcstr(np.median(b["tmptime"]))),
                        (0.5, 0.5),
                        xycoords="axes fraction",
                        color="red",
                        ha="center",
                    )

        if not isinstance(species, str):
            # produce the MxNx3 array for to up 3 values of species (in R, G, B)
            img = np.zeros((b[species[0]].shape[1], b[species[0]].shape[2], 3)) + 1.0
            for i, s in enumerate(species):
                im = np.sum(b[s], 0).astype(np.float64)
                # im[im < 0.01] += 0.1e-10

                if inverted:
                    im = 1.0 - norm(np.log10(im))
                    for j in (0, 1, 2):
                        if j != i:
                            img[..., j] *= im
                    tot = np.sum(1.0 - img)
                else:
                    img[..., i] *= norm(np.log10(im))
                    tot = np.sum(img)

        else:
            img = np.sum(b[species], 0)
            img[img < 0.01] += 0.1e-10
            img = np.log10(img)
            tot = np.sum(img)
        if verbose:
            print("Total scaled: %e" % tot)
            # print 'Fraction good = %2.0f%%' % (np.float(np.sum(np.isfinite(img))) / (img.size) * 100.)
            # print 'Min, mean, max = ', np.min(img), np.mean(img), np.max(img)

        if check_overlap and (extent[0] < last_finish):
            raise ValueError("Blocks overlap: Last finish = %f, this start = %f" % (last_finish, extent[0]))

        if FUDGE_FIX_HANS_IMA_TIME_BUG:
            # print extent, last_finish
            if abs(extent[0] - last_finish) < 20.0:  # if there's 20s or less between blocks
                if verbose:
                    print("\tFudging extent: Adjusting start by %fs" % (extent[0] - last_finish))
                extent[0] = last_finish  # squeeze them together

        if inverted:
            name = cmap.name
            if name[-2:] == "_r":
                name = name[:-2]
            else:
                name = name + "_r"
            cmap = getattr(plt.cm, name)

        if extent[1] < start:
            # if verbose:
            print("Dumping block (B)", start - extent[1])
            continue
        if extent[0] > finish:
            print("Dumping block (A)", extent[0] - finish)
            continue

        ims.append(plt.imshow(img, extent=extent, origin="upper", interpolation="nearest", cmap=cmap, norm=norm))

        last_finish = extent[1]

    if ims:
        plt.xlim(start, finish)
        plt.ylim(min_energy, max_energy)
        cbar_im = ims[0]
    else:
        plt.ylim(10.0, 60000)  # guess
        # invisible image for using with colorbar
        cbar_im = plt.imshow(np.zeros((1, 1)), cmap=cmap, norm=norm, visible=False)

    plt.yscale("log")
    celsius.ylabel("E / eV")

    if colorbar:
        ## make_colorbar_cax is doing something weird to following colorbars...
        # if not isinstance(species, basestring):
        #     img = np.zeros((64,len(species),3)) + 1.
        #     cax = celsius.make_colorbar_cax(width=0.03)
        #     for i, s in enumerate(species):
        #         for j in (0,1,2):
        #             if j != i:
        #                 img[:,i,j] = np.linspace(0., 1., 64)
        #     # plt.sca(cax)
        #     plt.imshow(img, extent=(0, 3, vmin, vmax), interpolation='nearest', aspect='auto')
        #     plt.xticks([0.5, 1.5, 2.5], label.split(', '))
        #     plt.xlim(0., 3.)
        #     cax.yaxis.tick_right()
        #     cax.xaxis.tick_top()
        #     plt.yticks = [2,3,4,5,6]
        #     cax.yaxis.set_label_position('right')
        #     plt.ylabel(r'$Flux / cm^{-2}s^{-1}$')
        #     # plt.sca(ax)
        # else:
        ticks = np.arange(int(vmin), int(vmax) + 1, dtype=int)
        plt.colorbar(cbar_im, cax=celsius.make_colorbar_cax(), ticks=ticks).set_label(label)

    if return_val:
        if return_val == "IMAGES":
            del blocks
            return ims
        elif return_val == "BLOCKS":
            return blocks
        else:
            print("Unrecognised return_value = " + str(return_value))

    del blocks
    del ims
    return
Ejemplo n.º 2
0
def plot_els_spectra(
    start,
    finish,
    sector="SUM",
    colorbar=True,
    ax=None,
    blocks=None,
    return_val=None,
    verbose=False,
    check_times=True,
    vmin=None,
    vmax=None,
    cmap=None,
    norm=None,
    die_on_empty_blocks=False,
    **kwargs
):
    """
    Plot ASPERA/ELS spectra from start - finish.
    sector = int from 0 - 15 to select single sector to plot.
    sector = 'SUM' to integrate over all
    sector = 'MEAN' to average over all

    Shapes of the stuff in each block (215 = time!)
        altElec (1, 215)
        latElec (1, 215)
        zmsoElec (1, 215)
        dEElec (128, 1)
        ymsoElec (1, 215)
        xmsoElec (1, 215)
        tElec (1, 215)
        fElec (16, 128, 215)
        longElec (1, 215)
        EElec (128, 1)

    New versions:
        elslevels (128, 112)
        elsmatrix (128, 16, 783)
        elstimes (1, 783)
        elssectors (1, 16)
        elsleveltimes (1, 112)
        elsdeltatimes (128, 112)
    """

    if not blocks:
        blocks = read_els(start, finish, verbose=verbose, **kwargs)

    if ax is None:
        ax = plt.gca()
    plt.sca(ax)
    ax.set_axis_bgcolor("lightgrey")

    if not cmap:
        cmap = Spectral_r
        cmap.set_bad("white")

    ims = []

    last_finish = -9e99

    # label = r'Flux / $cm^{-2}s^{-1}$'
    label = "Counts"

    # Make sure we set the ylimits correctly by tracking min and max energies
    min_energy = 1e99
    max_energy = -1e99

    cbar_ticks = np.array((7, 8, 9, 10, 11))

    # Establish function to handle the data
    if isinstance(sector, str):
        if sector.lower() == "mean":
            process = lambda x: np.nanmean(x, 1)
            # if vmin is None:
            #     vmin = 7.
            # if vmax is None:
            #     vmax = 11.

        elif sector.lower() == "sum":
            process = lambda x: np.nansum(x, 1)
            # if vmin is None:
            #     vmin = 7. + 1.
            # if vmax is None:
            #     vmax = 11. + 1.
            # cbar_ticks += 1
        else:
            raise ValueError("Unrecognized argument for sector: %s" % sector)
    else:
        process = lambda x: x[:, sector, :]
        # if vmin is None:
        #     vmin = 7.
        # if vmax is None:
        #     vmax = 11.

    if vmin is None:
        vmin = 0
    if vmax is None:
        vmax = 4

    if not norm:
        norm = plt.Normalize(vmin, vmax, clip=False)

    norm = None

    for b in blocks:
        # min(abs()) to account for negative values in E table
        extent = [
            celsius.matlabtime_to_spiceet(np.min(b["elstimes"])),
            celsius.matlabtime_to_spiceet(np.max(b["elstimes"])),
            np.min(np.abs(b["elslevels"])),
            np.max(b["elslevels"]),
        ]

        if extent[2] < min_energy:
            min_energy = extent[2]

        if extent[3] > max_energy:
            max_energy = extent[3]
        print(extent)
        # if check_times:
        #     spacing = 86400.*np.mean(np.diff(b['tElec']))
        #     if spacing > 15.:
        #         raise ValueError("Resolution not good? Mean spacing = %fs " % spacing )

        img = process(b["elsmatrix"])
        # img[img < 10.] = np.min(img)
        img = np.log10(img)

        if verbose:
            print(
                "Fraction good = %2.0f%%" % (np.float(np.sum(np.isfinite(img))) / (img.shape[0] * img.shape[1]) * 100.0)
            )
            # print 'Min, mean, max = ', np.nanmin(img), np.nanmean(img), np.nanmax(img)

        if extent[0] < last_finish:
            s = "Blocks overlap: Last finish = %f, this start = %f" % (last_finish, extent[0])
            if check_times:
                raise ValueError(s)
            else:
                print(s)

        # e = extent[2]
        # extent[2] = extent[3]
        # extent[3] = e

        ims.append(plt.imshow(img, extent=extent, origin="upper", interpolation="nearest", cmap=cmap, norm=norm))

        last_finish = extent[1]

    number_of_blocks = len(blocks)

    if blocks:
        plt.xlim(start, finish)
        plt.ylim(min_energy, max_energy)

        cbar_im = ims[0]

    else:
        plt.ylim(1e0, 1e4)
        # need to create an empty image so that colorbar functions
        cbar_im = plt.imshow(np.zeros((1, 1)), cmap=cmap, norm=norm, visible=False)

    plt.ylim(min_energy, max_energy)
    plt.yscale("log")
    # plt.ylabel('E / eV')
    print("ELS PLOT: Time is not accurate to more than ~+/- 4s for now.")

    if colorbar:
        if ims:
            plt.colorbar(cbar_im, cax=celsius.make_colorbar_cax(), ticks=cbar_ticks).set_label(label)

    if return_val:

        if return_val.upper() == "IMAGES":
            del blocks
            return ims
        elif return_val.upper() == "BLOCKS":
            del ims
            return blocks
        else:
            print("Unrecognised return_value = " + str(return_value))

    del blocks
    del ims
    return number_of_blocks