Пример #1
0
def plot_ima_mass_matrix(start, finish, product=None, colorbar=True, ax=None, blocks=None, **kwargs):
    """ Integrate to produce a mass-matrix from start-finish, processing azimuths"""

    if (finish - start) < aspera_scan_time:
        raise ValueError("Duration too short: %d" % (finish - start))

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

    if ax is None:
        ax = plt.gca()

    plt.sca(ax)

    products_to_process = ("CO2", "H", "O", "Hsp", "alpha", "O2", "He")
    if product:
        if not hasattr(product, "__iter__"):
            products_to_process = [product]
        else:
            products_to_process = product

    img = np.zeros_like(blocks[0]["sumions"])

    for b in blocks:
        inx, = np.where((b["tmptime"] > start) & (b["tmptime"] < finish))
        if inx.shape[0]:
            for p in products_to_process:
                img += np.sum(b[p][:, :, inx], 2)

    plt.imshow(img, origin="lower")
    if colorbar:
        plt.colorbar(cax=celsius.make_colorbar_cax())

    return img
Пример #2
0
    def plot_timeseries(self, ax=None, vmin=None, vmax=None,
            colorbar=False, label=True):

        if vmin is None:
            vmin = self.vmin

        if vmax is None:
            vmax = self.vmax

        if ax is None:
            ax = plt.gca()
        plt.sca(ax)
        plt.cla()
        plt.imshow(self.tser_arr[::-1,:], vmin=vmin, vmax=vmax,
            interpolation='Nearest', extent=self.extent, origin='upper',aspect='auto')
        plt.xlim(self.extent[0], self.extent[1])
        plt.ylim(self.extent[2], self.extent[3])
        # plt.vlines(self.ionogram_list[0].time, self.extent[2], self.extent[3], 'r')
        if label:
           celsius.ylabel('f / MHz')

        if colorbar:
            old_ax = plt.gca()
            plt.colorbar(
                    cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks
                ).set_label(r"$Log_{10} V^2 m^{-2} Hz^{-1}$")
            plt.sca(old_ax)
Пример #3
0
    def plot_frequency_altitude(self, f=2.0, ax=None, median_filter=False,
        vmin=None, vmax=None, altitude_range=(-99.9, 399.9), colorbar=False, return_image=False, annotate=True):

        if vmin is None:
            vmin = self.vmin

        if vmax is None:
            vmax = self.vmax

        if ax is None:
            ax = plt.gca()

        plt.sca(ax)
        plt.cla()
        freq_extent = (self.extent[0], self.extent[1],
            altitude_range[1], altitude_range[0])

        i = self.ionogram_list[0]
        inx = 1.0E6* (i.frequencies.shape[0] * f) / (i.frequencies[-1] - i.frequencies[0])
        img = self.tser_arr_all[:,int(inx),:]

        new_altitudes = np.arange(altitude_range[0], altitude_range[1], 14.)
        new_img = np.zeros((new_altitudes.shape[0], img.shape[1])) + np.nan

        for i in self.ionogram_list:
            e = int( round((i.time - self.extent[0]) / ais_code.ais_spacing_seconds ))

            pos = mex.iau_r_lat_lon_position(float(i.time))
            altitudes = pos[0] - ais_code.speed_of_light_kms * ais_code.ais_delays * 0.5 - mex.mars_mean_radius_km
            s = np.argsort(altitudes)
            new_img[:, e] = np.interp(new_altitudes, altitudes[s], img[s,e], left=np.nan, right=np.nan)

        plt.imshow(new_img, vmin=vmin, vmax=vmax,
            interpolation='Nearest', extent=freq_extent, origin='upper', aspect='auto')

        plt.xlim(freq_extent[0], freq_extent[1])
        plt.ylim(*altitude_range)

        ax.set_xlim(self.extent[0], self.extent[1])
        ax.xaxis.set_major_locator(celsius.SpiceetLocator())

        celsius.ylabel(r'Alt./km')
        if annotate:
            plt.annotate('f = %.1f MHz' % f, (0.02, 0.9),
                    xycoords='axes fraction', color='cyan', verticalalignment='top', fontsize='small')

        if colorbar:
            old_ax = plt.gca()
            plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks).set_label(r"$Log_{10} V^2 m^{-2} Hz^{-1}$")
            plt.sca(old_ax)

        if return_image:
            return new_img, freq_extent, new_altitudes
Пример #4
0
    def plot_profiles(self, ax=None, vmin=4., vmax=5.5, cmap=None,
                                cmticks=None, log=True, substitute_fp=None, **kwargs):
        """
        Inverts the profiles, plots them versus time and altitude, color coded to density
        Does not show the 'first step' between the S/C plasma density and the first reflection
        """
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)
        ax.set_axis_bgcolor("gray")

        if cmap is None:
            cmap = matplotlib.cm.hot
        if cmticks is None:
            cmticks = [3, 4, 5, 6]
        n_profiles = int((self.extent[1] - self.extent[0]) / ais_code.ais_spacing_seconds) + 1
        ranges = np.arange(80., 350., 1.)
        times  = np.arange(self.extent[0], self.extent[1], ais_code.ais_spacing_seconds)
        img = np.zeros((len(times), len(ranges))) + np.nan

        label = r'$n_e$ / cm$^{-3}$'
        if log:
            f = np.log10
            label = r'log ' + label
        else:
            f = lambda x: x

        if substitute_fp is None:
            subf = lambda t: 0.
        else:
            if hasattr(substitute_fp, '__call__'):
                subf = lambda t: substitute_fp(t)
            else:
                subf = lambda t: substitute_fp

        for i, d in enumerate(self.digitization_list):
            if d.is_invertible():
                d.invert(substitute_fp=subf(d.time))
                if d.altitude.size:
                    ii = round((float(d.time) - times[0]) / ais_code.ais_spacing_seconds)
                    img[ii,:] = np.interp(ranges, d.altitude[-1:0:-1],
                                            f(d.density[-1:0:-1]),
                                            right=np.nan, left=np.nan)[::-1]

        extent = (self.extent[0], self.extent[1], np.nanmin(ranges), np.nanmax(ranges))
        plt.imshow(img.T, interpolation='Nearest', extent=extent,
                origin='upper',aspect='auto', vmin=vmin, vmax=vmax, cmap=cmap)

        celsius.ylabel("alt / km")

        old_ax = plt.gca()
        plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=cmticks, **kwargs).set_label(label)
        plt.sca(old_ax)
Пример #5
0
def plot_field_topology(description, ax=None, colorbar=True, fname=None, limits=True,
                    circ_axis=True, vmin=0., vmax=100., labels=True, full_range=True, **kwargs):
    """
    Brain field topology maps.  Ammended/edited by Rob as well, so include him.
    """

    if not description in ALL_DESCRIPTIONS:
        raise KeyError("%s not one of accepted descriptions: %s" %
                                        (description, str(ALL_DESCRIPTIONS)))

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

    if fname is None:
        fname = get_file()

    data = readsav(fname, verbose=False)

    img = data[description]

    if full_range:
        img2 = np.hstack((img, img, img))
        out = plt.imshow(img2, origin='lower', extent=(-360., 720., -90., 90.),
                            interpolation='nearest', vmin=vmin, vmax=vmax, **kwargs)
    else:
        out = plt.imshow(img, origin='lower', extent=(0., 360., -90., 90.),
                                interpolation='nearest', vmin=vmin, vmax=vmax, **kwargs)

    if limits:
        plt.xlim(0., 360.)
        plt.ylim(-90., 90)

    if circ_axis:
        ax.xaxis.set_major_locator(celsius.CircularLocator())
        ax.yaxis.set_major_locator(celsius.CircularLocator())

    if labels:
        plt.ylabel("Latitude / deg")
        plt.xlabel("Longitude / deg")

    if colorbar:
        c = plt.colorbar(cax=celsius.make_colorbar_cax())
        if labels:
            c.set_label(description.replace('_', ' '))

        out = (out, c)

    return out
Пример #6
0
def plot_swea_l2_summary(swea_data, max_times=4096, cmap=None, norm=None,
        labels=True, ax=None, colorbar=True):

    energy_range = (2, 4000.)
    def_range    = (1e6, 1e9)

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    if cmap is None: cmap = 'Spectral_r'
    if norm is None: norm = LogNorm(def_range[0], def_range[1])

    if not 'def' in swea_data:
        print('Data is empty?')
        # extent = (t[0], t[-1], swea_data['energy'][0], swea_data['energy'][-1])
        d = np.empty(4).reshape((2,2)) + np.nan
        t = plt.xlim()
    else:
        d = swea_data['def']
        t = swea_data['time']

        if d.shape[1] > max_times:
            n = int(np.floor(d.shape[1] / max_times))
            d = d[:,::n]
            t = t[::n]

        energy_range = (swea_data['energy'][0], swea_data['energy'][-1])

    extent = (t[0], t[-1], energy_range[0], energy_range[1])

    img = plt.imshow(
        d, extent=extent, interpolation='nearest', origin='lower',
        norm=norm, cmap=cmap
    )
    plt.xlim(t[0], t[-1])

    plt.yscale('log')
    plt.ylim(energy_range[0], energy_range[1])

    if labels:
        plt.ylabel("E / eV")

    if colorbar:
        plt.colorbar(cax=celsius.make_colorbar_cax()).set_label('SWEA D.E.F.')

    return img
Пример #7
0
    def plot_frequency_range(self, f_min=0., f_max=0.2, ax=None, median=False,
        vmin=None, vmax=None, colorbar=False, max_value=False):

        if vmin is None:
            vmin = self.vmin

        if vmax is None:
            vmax = self.vmax

        if ax is None:
            ax = plt.gca()

        plt.sca(ax)
        plt.cla()
        freq_extent = (self.extent[0], self.extent[1],
            ais_code.ais_max_delay*1E3, ais_code.ais_min_delay*1E3)

        i = self.ionogram_list[0]
        inx, = np.where((i.frequencies > f_min*1E6) & (i.frequencies < f_max*1E6))

        if inx.shape[0] < 2:
            raise ValueError("Only %d frequency bins selected." % inx.shape[0])
        print("Averaging over %d frequency bins" % inx.shape[0])

        if median:
            if inx.shape[0] < 3:
                raise ValueError("Median here only really makes sense for 3 or more bins")
            img = np.median(self.tser_arr_all[:,inx,:],1)
        elif max_value:
            img = np.max(self.tser_arr_all[:,inx,:],1)
        else:
            img = np.mean(self.tser_arr_all[:,inx,:],1)
        plt.imshow(img, vmin=vmin, vmax=vmax,
            interpolation='Nearest', extent=freq_extent, origin='upper',aspect='auto')

        plt.xlim(freq_extent[0], freq_extent[1])
        plt.ylim(freq_extent[2], freq_extent[3])
        # plt.vlines(i.time,freq_extent[2],freq_extent[3], 'r')
        celsius.ylabel(r'$\tau_D / ms$' '\n' '%.1f-%.1f MHz' % (f_min, f_max))
        # plt.annotate('f = %.1f - %.1f MHz' % (f_min, f_max), (0.02, 0.9), xycoords='axes fraction',
            # color='grey', verticalalignment='top', fontsize='small')

        if colorbar:
            old_ax = plt.gca()
            plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks).set_label(r"$Log_{10} V^2 m^{-2} Hz^{-1}$")
            plt.sca(old_ax)
Пример #8
0
def plot_static_l2_summary(static_data, plot_type='Energy',
        max_times=4096, cmap=None, norm=None,
        labels=True, ax=None, colorbar=True):

    if not 'static_kind' in static_data:
        raise ValueError("Data supplied not from static?")

    if not static_data['static_kind'] == 'c0':
        raise ValueError("I only know about C0, for now")

    if cmap is None: cmap = 'Spectral_r'
    if norm is None: norm = LogNorm(1e3, 1e9)

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    imgs = []

    x0, x1 = plt.xlim()

    for extent, data in static_data['blocks']:
        if extent[1] < x0: continue
        if extent[0] > x1: continue

        img = plt.imshow(
            data, extent=extent, interpolation='nearest', origin='lower',
            norm=norm, cmap=cmap
        )
        imgs.append(img)
    plt.yscale('log')
    # plt.xlim(t0, t1)
    plt.ylim(extent[2], extent[3])

    if labels:
        plt.ylabel("E / eV")

    if colorbar:
        plt.colorbar(cax=celsius.make_colorbar_cax()).set_label('static D.E.F.')

    return imgs
Пример #9
0
def plot_swia_l2_summary(swia_data, max_times=4096, cmap=None, norm=None,
        labels=True, ax=None, colorbar=True):

    if not 'def' in swia_data:
        print('No data given?')
        return

    d = swia_data['def']
    t = swia_data['time']

    if d.shape[1] > max_times:
        n = int(np.floor(d.shape[1] / max_times))
        d = d[:,::n]
        t = t[::n]

    extent = (t[0], t[-1], swia_data['energy'][0], swia_data['energy'][-1])

    if cmap is None: cmap = 'Spectral_r'
    if norm is None: norm = LogNorm(1e6, 1e8)

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    img = plt.imshow(
        d, extent=extent, interpolation='nearest', origin='lower',
        norm=norm, cmap=cmap
    )
    plt.yscale('log')
    # plt.xlim(t0, t1)
    plt.ylim(swia_data['energy'][0], swia_data['energy'][-1])

    if labels:
        plt.ylabel("E / eV")

    if colorbar:
        plt.colorbar(cax=celsius.make_colorbar_cax()).set_label('SWIA D.E.F.')

    return img
Пример #10
0
    def plot_frequency(self, f=2.0, ax=None, median_filter=False,
        vmin=None, vmax=None, colorbar=False):

        if vmin is None:
            vmin = self.vmin

        if vmax is None:
            vmax = self.vmax

        if ax is None:
            ax = plt.gca()
        plt.sca(ax)
        plt.cla()
        freq_extent = (self.extent[0], self.extent[1],
            ais_code.ais_max_delay*1E3, ais_code.ais_min_delay*1E3)

        i = self.ionogram_list[0]
        inx = 1.0E6* (i.frequencies.shape[0] * f) / (i.frequencies[-1] - i.frequencies[0])
        img = self.tser_arr_all[:,int(inx),:]
        # img -= np.mean(img, 0)
        plt.imshow(img, vmin=vmin, vmax=vmax,
            interpolation='Nearest', extent=freq_extent, origin='upper',aspect='auto')
        # plt.imshow(img, interpolation='Nearest', extent=freq_extent, origin='upper',aspect='auto')

        plt.xlim(freq_extent[0], freq_extent[1])
        plt.ylim(freq_extent[2], freq_extent[3])
        # plt.vlines(i.time,freq_extent[2],freq_extent[3], 'r')
        celsius.ylabel(r'$\tau_D / ms$' '\n' '%.1f MHz' % f)
        # plt.annotate('f = %.1f MHz' % f, (0.02, 0.9), xycoords='axes fraction',
        #             color='grey', verticalalignment='top', fontsize='small')

        if colorbar:
            old_ax = plt.gca()
            plt.colorbar(cax = celsius.make_colorbar_cax(),
                        ticks=self.cbar_ticks).set_label(
                                r"$Log_{10} V^2 m^{-2} Hz^{-1}$")
            plt.sca(old_ax)
Пример #11
0
def plot_surface_map(orbits, ax=None, param="time", cmap=None, norm=None, **kwargs):
    import mars.field_models
    import pickle
    from matplotlib.cm import summer

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    if cmap is None:
        cmap = summer

    setup_lat_lon_ax(ax=ax)

    try:
        mars.field_models.plot_lat_lon_field(value="|B|", cax=celsius.make_colorbar_cax(half=True, upper=True))
    except NotImplementedError as e:
        pass

    if not "ais_index" in celsius.datastore:
        celsius.datastore["ais_index"] = mex.ais.get_ais_index()
    g = celsius.datastore["ais_index"]
    g = [v for k, v in g.items() if k in orbits]

    if not g:
        raise ValueError("No data?")

    for gg in g:
        gg["iau_pos"][2, :] = celsius.deg_unwrap(gg["iau_pos"][2, :])

    if param is None:
        for gg in g:
            for i in (-1, 0, 1):
                plt.plot(gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], **kwargs)

    if param == "sza":
        if norm is None:
            norm = plt.Normalize(vmin=0.0, vmax=180.0)
        title = "SZA / deg"

    elif param == "time":
        if norm is None:
            norm = plt.Normalize(vmin=mex.orbits[min(orbits)].start, vmax=mex.orbits[max(orbits)].finish)
        title = "Time / ET"

    elif param == "alt":
        if norm is None:
            norm = plt.Normalize(vmin=0.0, vmax=mex.mars_mean_radius_km)
        title = "Alt. / km"

    else:
        raise ValueError("Unrecognised parameter % s" % param)

    cmap = summer
    lc = None

    lc_kw = dict(cmap=cmap, norm=norm, linewidths=4, max_step=10.0)

    for gg in g:
        for i in (-1.0, 0.0, 1.0):
            if param == "sza":
                lc = celsius.map_along_line(
                    gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], gg["sza"], time=gg["time"], **lc_kw
                )
            if param == "time":
                lc = celsius.map_along_line(
                    gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], gg["time"], time=gg["time"], **lc_kw
                )
            if param == "alt":
                lc = celsius.map_along_line(
                    gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], gg["iau_pos"][0, :], time=gg["time"], **lc_kw
                )

            # plt.scatter(gg['iau_pos[2,:], gg['iau_pos[1,:], c=gg['sza,
            #             s=10., vmin=30, vmax=150, edgecolor='none')
    if lc:
        c = plt.colorbar(lc, cax=celsius.make_colorbar_cax(half=True, upper=False))
        c.set_label(title)
    else:
        raise ValueError("Nothing mapped :(")

    plt.sca(ax)
    return lc
Пример #12
0
def plot_aspera_els(start, finish=None, verbose=False, ax=None, colorbar=True,
                        vmin=None, vmax=None, cmap=None, safe=True):
    """docstring for plot_aspera_els"""
    if cmap is None:
        cmap = plt.cm.Spectral_r

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

    if finish is None:
        finish = start + 86400.

    if vmin is None:
        vmin = 5.

    if vmax is None:
        vmax = 9.

    no_days = (finish - start) / 86400.

    if verbose: print('Plotting ASPERA/ELS between %s and %s...' % (celsius.utcstr(start, 'ISOC'), celsius.utcstr(finish, 'ISOC')))

    directory = mex.data_directory + 'aspera/els/'

    all_files_to_read = []

    for et in np.arange(start - 10., finish + 10., 86400.):
        dt = celsius.spiceet_to_datetime(et)
        f_name = directory + 'MEX_ELS_EFLUX_%4d%02d%02d_*.cef' % (dt.year, dt.month, dt.day)
        all_day_files = glob.glob(f_name)
        if not all_day_files:
            if verbose: print("No files matched %s" % f_name)
        else:
            all_files_to_read.extend(all_day_files)

    success = False
    all_extents = []
    for f_name in all_files_to_read:
        try:
            # Find energy bins:
            with open(f_name, 'r') as f:
                line_no = 0
                while line_no < 43:
                    line_no += 1
                    line = f.readline()
                    if 'DATA = ' in line:
                        energy_bins = np.fromstring(line[7:], sep=',')
                        energy_bins.sort()
                        break
                else:
                    raise IOError("No ENERGY_BINS info found in header")

            data = np.loadtxt(f_name, skiprows = 43, converters={1:lambda x: celsius.utcstr_to_spiceet(x[:-1])})

            if data.shape[1] != (energy_bins.shape[0] + 2):
                raise ValueError("Size of ENERGY_BINS and DATA doesn't match")

            # Check timing:
            dt = np.diff(data[:,1])
            spacing = np.median(dt)
            # checks = abs(dt - spacing) > (spacing/100.)
            # if np.any(checks):
            #     # raise ValueError("Spacing is not constant: %d differ by more than 1%% of %f:" % (np.sum(checks), spacing))
            #     print "Spacing is not constant: %d differ by more than 1%% of %f (Maximum = %f):" % (np.sum(checks), spacing, max(abs(dt - spacing)))
            #
            # if safe and (max(abs(dt - spacing)) > 10.):
            #     print '-- To big spacing - dumping'
            #     continue

            # Interpolate to constant spacing:
            n_records = int((data[-1,1] - data[0,1]) / spacing)
            new_data = np.empty((n_records, data.shape[1])) + np.nan
            new_data[:,1] = np.linspace(data[0,1], data[-1,1], n_records)
            for i in range(3, data.shape[1]):
                new_data[:,i] = np.interp(new_data[:,1],data[:,1], data[:,i], left=np.nan, right=np.nan)

            data = new_data

            extent = (data[0,1], data[-1,1], energy_bins[0], energy_bins[-1])

            if (extent[0] > finish) or (extent[1] < start):
                if verbose:
                    print("This block not within plot range - dumping")
                continue

            all_extents.append(extent)
            if verbose:
                print('Plotting ASPERA ELS block, Time: %s - %s, Energy: %f - %f' % (
                                celsius.utcstr(extent[0],'ISOC'), celsius.utcstr(extent[1],'ISOC'),
                                extent[2], extent[3]))
                print('Shape = ', data.shape)

            plt.imshow(np.log10(data[:,3:].T), interpolation="nearest", aspect='auto', extent=extent, vmin=vmin, vmax=vmax, cmap=cmap)
            success = True
        except IOError as e:
            if verbose:
                print('Error reading %f' % f_name)
                print('--', e)
            continue

    if success and colorbar:
        plt.xlim(start, finish)
        plt.ylim(max([e[2] for e in all_extents]), min([e[3] for e in all_extents]))
        celsius.ylabel('E / eV')
        plt.yscale('log')
        cmap.set_under('w')
        old_ax = plt.gca()
        plt.colorbar(cax=celsius.make_colorbar_cax(), cmap=cmap, ticks=[5,6,7,8,9])
        plt.ylabel(r'log$_{10}$ D.E.F.')
        plt.sca(old_ax)
Пример #13
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
Пример #14
0
def lpw_plot_iv(s, boom=1, ax=None, cmap=None, norm=None,
    start=None, finish=None,
    voltage=None, max_times=8912, imin=None, imax=None,
    labels=True, colorbar=True, full_resolution=False, log_abs=True):
    """Plot LP IV sweeps as a time series. Interpolation to regular voltage and time axis as appropriate for presentation purposes, but don't do science with the results."""

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    if cmap is None:
        plt.set_cmap('Spectral_r')
        cmap = plt.get_cmap()
        cmap.set_bad('grey')

    t0 = s['time'][0]
    t1 = s['time'][-1]

    if voltage is None:
        voltage = np.linspace(-20., 20., 512)

    if full_resolution:
        voltage = np.arange(-20., 20., 0.01)

    n_times = np.floor((t1 - t0) / 4.)

    if (n_times > 4096) and full_resolution:
        print('You are attempting to create a very, very large image...')

    if (n_times < max_times) or full_resolution:
        dt = 4.
    else:
        dt = (t1 - t0) / max_times

    tnew = np.arange(t0, t1, dt)

    if not norm:
        norm = LogNorm(1e-9, 1e-3)
        if not log_abs:
            norm = plt.Normalize(1e-3, 1e-3)



    extent = (t0, t1, voltage[0], voltage[-1])
    # Compute expansion of frequency axis
    # freq_inx = []
    # fnext = s['freq'][1]
    # f_inx = 0
    # i = 0
    # while True:
    #     if fnext > fnew[i]:
    #         freq_inx.append(f_inx)
    #         i+=1
    #         if i == max_frequencies: break
    #     else:
    #         f_inx += 1
    #         fnext = s['freq'][f_inx]
    # freq_inx = np.array(freq_inx)

    # Interpolate voltages
    tmp = []
    t = t0
    img = np.empty((voltage.shape[0], tnew.shape[0])) + np.nan
    inx_new = 0
    inx_old = boom
    for current, old_voltage in zip(s['current'], s['volt']):
        i = boom
        while i < current.shape[1]:
            while tnew[inx_new] < s['time'][inx_old]:
                img[:, inx_new] = np.interp(voltage, old_voltage[:,i],
                        current[:, i],
                        left=np.nan, right=np.nan)
                inx_new += 1
                if inx_new >= tnew.shape[0]:
                    break
            i += 2
            inx_old += 2
            if inx_new >= tnew.shape[0]:
                break


    # raise RuntimeError()
    # print(img.shape)
    print(extent)
    if log_abs:
        img = np.abs(img)

    img_obj = plt.imshow(img, cmap=cmap, norm=norm, extent=extent,
            origin='lower', interpolation='nearest')

    # plt.yscale('log')
    plt.ylim(voltage[0], voltage[-1])
    plt.xlim(t0, t1)

    if labels:
        plt.ylabel(r'U$_{Bias}$ / V')
    if colorbar:
        cbar = plt.colorbar(cax=celsius.make_colorbar_cax())
        cbar.set_label(r'i / A')
    else:
        cbar = None

    return img, img_obj, cbar
Пример #15
0
def lpw_plot_spec(s, ax=None, cmap=None, norm=None,
    max_frequencies=512, max_times=2048, fmin=None, fmax=None,
    labels=True, colorbar=True, full_resolution=False):
    """Transform and plot a spectra dictionary generated by lpw_load.
Doesn't interpolate linearly, but just rebins data.  Appropriate for presentation purposes, but don't do science with the results."""

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    if cmap is None: cmap = 'Spectral_r'
    if norm is None: norm = LogNorm(1e-16, 1e-8)

    t0 = s['time'][0]
    t1 = s['time'][-1]
    f0 = s['freq'][0]
    f1 = s['freq'][-1]

    n_times = np.floor((t1 - t0) / 4.)

    if (n_times > 4096) and full_resolution:
        print('You are attempting to create a very, very large image...')

    if (n_times < max_times) or full_resolution:
        dt = 4.
    else:
        dt = (t1 - t0) / max_times
    tnew = np.arange(t0, t1, dt)

    minf = np.min(np.diff(s['freq']))

    if fmin is not None: f0 = fmin # Hz
    if fmax is not None: f1 = fmax

    extent = (t0, t1, f0, f1)

    if full_resolution:
        fnew = 10.**np.arange(np.log10(f0), np.log10(f1), 0.01) # Approximate
        max_frequencies = fnew.shape[0]
    else:
        fnew = 10.**np.linspace(np.log10(f0), np.log10(f1-1.), max_frequencies)

    # Compute expansion of frequency axis
    freq_inx = []
    fnext = s['freq'][1]
    f_inx = 0
    i = 0
    while True:
        if fnext > fnew[i]:
            freq_inx.append(f_inx)
            i+=1
            if i == max_frequencies: break
        else:
            f_inx += 1
            fnext = s['freq'][f_inx]
    freq_inx = np.array(freq_inx)

    # Compute expansion of time axis
    t_inx = []
    tnext = s['time'][1]
    time_inx = 0
    i = 0
    while True:
        if tnext > tnew[i]:
            t_inx.append(time_inx)
            i+=1
            if i == tnew.shape[0]: break
        else:
            time_inx += 1
            tnext = s['time'][time_inx]
    t_inx = np.array(t_inx)

    img = s['spec'][...,t_inx][freq_inx]
    img_obj = plt.imshow(img, cmap=cmap, norm=norm, extent=extent,
            origin='lower', interpolation='nearest')

    plt.yscale('log')
    plt.ylim(f0, f1)
    plt.xlim(t0, t1)

    if labels:
        plt.ylabel('f / Hz')
    if colorbar:
        cbar = plt.colorbar(cax=celsius.make_colorbar_cax())
        cbar.set_label(r'V$^2$ m$^{-2}$ Hz$^{-1}$')
    else:
        cbar = None

    return img, img_obj, cbar
Пример #16
0
    def modb_along_orbit(self, ax=None, annotate=True, bg_color='dimgrey', cmap=None, vmin=0., vmax=20.):
        if ax is None:
            ax = plt.gca()

        if cmap is None:
            cmap = plt.cm.autumn
            cmap.set_bad('dimgrey',0.)
            cmap.set_under('dimgrey',0.)

        td_cyclotron_list = [d for d in self.digitization_list if np.isfinite(d.td_cyclotron)]

        plt.sca(ax)
        mex.plot_planet(lw=3.)
        mex.plot_bs(lw=1., ls='dashed', color='k')
        mex.plot_mpb(lw=1., ls='dotted', color='k')
        ax.set_aspect('equal','box')
        plt.xlim(2,-2)
        plt.autoscale(False,tight=True)
        plt.ylim(0., 1.999)

        if annotate:
            plt.annotate('%d' % self.orbit, (0.05, 0.85),
                        xycoords='axes fraction', va='top')

        def f_x(pos):
            return pos[0] / mex.mars_mean_radius_km
        def f_y(pos):
            return np.sqrt(pos[1]**2. + pos[2]**2.) / mex.mars_mean_radius_km
        # def f_y(pos):
        #     return pos[2] / mex.mars_mean_radius_km

        plt.plot( f_x(self.mso_pos), f_y(self.mso_pos),
                color=bg_color, lw=2., zorder=-10)

        inx = np.interp(np.array([d.time for d in self.ionogram_list]),
                                        self.t, np.arange(self.t.shape[0]))
        inx = inx.astype(int)
        plt.plot(f_x(self.mso_pos[:,inx]), f_y(self.mso_pos[:,inx]),
                color=bg_color, ls='None',marker='o', ms=8., mew=0., mec=bg_color, zorder=-9)

        if td_cyclotron_list:
            val = np.empty_like(self.t) + np.nan
            for t, v in [(float(f.time), 1E9 * ais_code.td_to_modb(f.td_cyclotron))
                                                        for f in td_cyclotron_list]:
                val[np.abs(self.t - t) < ais_code.ais_spacing_seconds] = v

            points = np.array([f_x(self.mso_pos), f_y(self.mso_pos)]).T.reshape(-1, 1, 2)
            segments = np.concatenate([points[:-1], points[1:]], axis=1)
            lc = LineCollection(segments, cmap=cmap,
                    norm=plt.Normalize(vmin=vmin, vmax=vmax, clip=True))

            lc.set_array(val)
            lc.set_linewidth(5)
            plt.gca().add_collection(lc)
        else:
            lc = None
        plt.ylabel(r'$\rho / R_M$')
        # plt.ylabel(r'$z / R_M$')
        plt.xlabel(r'$x / R_M$')
        if lc:
            old_ax = plt.gca()
            plt.colorbar(lc, cax = celsius.make_colorbar_cax(offset=0.001, height=0.8)
                        ).set_label(r'$|B| / nT$')
            plt.sca(old_ax)
Пример #17
0
    def density_along_orbit(self, ax=None, annotate=True, min_fp_local_length=0, bg_color='dimgrey', cmap=None, vmin=1., vmax=3.):
        if cmap is None:
            cmap = plt.cm.autumn
            cmap.set_bad('dimgrey',0.)
            cmap.set_under('dimgrey',0.)

        if ax is None:
            ax = plt.gca()

        fp_local_list = [d for d in self.digitization_list if np.isfinite(d.fp_local)]

        plt.sca(ax)
        mex.plot_planet(lw=3.)
        mex.plot_bs(lw=1., ls='dashed', color='k')
        mex.plot_mpb(lw=1., ls='dotted', color='k')
        ax.set_aspect('equal', 'box')
        plt.xlim(2,-2)
        plt.autoscale(False,tight=True)
        plt.ylim(0,1.9999)

        if annotate:
            plt.annotate('%d' % self.orbit, (0.05, 0.85), xycoords='axes fraction', va='top')

        def f_x(pos):
            return pos[0] / mex.mars_mean_radius_km
        def f_y(pos):
            return np.sqrt(pos[1]**2. + pos[2]**2.) / mex.mars_mean_radius_km
        # def f_y(pos):
        #     return pos[2] / mex.mars_mean_radius_km

        plt.plot( f_x(self.mso_pos), f_y(self.mso_pos),
                color=bg_color, lw=1., zorder=-10)

        inx = np.interp(np.array([d.time for d in self.ionogram_list]), self.t, np.arange(self.t.shape[0]))
        inx = inx.astype(int)

        plt.plot( f_x(self.mso_pos[:,inx]), f_y(self.mso_pos[:,inx]),
                color=bg_color, ls='None',marker='o', ms=8.,mew=0., mec=bg_color, zorder=-9)

        if fp_local_list:
            val = np.empty_like(self.t) + np.nan
            # for t, v in [(float(f.time), np.log10(ais_code.fp_to_ne(f.maximum_fp_local))) for f in fp_local_list]:
            #     val[np.abs(self.t - t) < ais_code.ais_spacing_seconds] = v

            for f in fp_local_list:
                t = float(f.time)
                # if (f.fp_local_error / f.fp_local) > 0.3:
                #     v = np.log10(20.)
                # else:
                v = np.log10(ais_code.fp_to_ne(f.fp_local))
                # print t, ais_code.fp_to_ne(f.fp_local), f.fp_local_error/f.fp_local > 0.3
                val[np.abs(self.t - t) < ais_code.ais_spacing_seconds] = v

            points = np.array([f_x(self.mso_pos), f_y(self.mso_pos)]).T.reshape(-1, 1, 2)
            segments = np.concatenate([points[:-1], points[1:]], axis=1)
            lc = LineCollection(segments, cmap=cmap, norm=plt.Normalize(vmin=vmin, vmax=vmax, clip=True))
            lc.set_array(val)
            lc.set_linewidth(5)
            plt.gca().add_collection(lc)
        else:
            lc = None

        plt.ylabel(r'$\rho / R_M$')
        # plt.ylabel(r'$z / R_M$')
        plt.xlabel(r'$x / R_M$')
        if lc:
            ticks = [i for i in range(10) if ((float(i)+0.1) > vmin) & ((float(i)-0.1) < vmax)]
            old_ax = plt.gca()
            plt.colorbar(lc, cax = celsius.make_colorbar_cax(offset=0.001, height=0.8),
                            ticks=ticks).set_label(r'$log_{10}\;n_e / cm^{-3}$')
            plt.sca(old_ax)
Пример #18
0
    def plot_profiles_delta(self, ax=None):
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)
        ax.set_axis_bgcolor("gray")

        n_profiles = int((self.extent[1] - self.extent[0]) / ais_code.ais_spacing_seconds) + 1
        ranges = np.arange(80., 300., 1.)
        times  = np.arange(self.extent[0], self.extent[1], ais_code.ais_spacing_seconds)
        img = np.zeros((len(times), len(ranges))) + np.nan

        for i, d in enumerate(self.digitization_list):
            if d.is_invertible():
                d.invert(substitute_fp=ais_code.ne_to_fp(4.))
                if d.altitude.size:
                    # as it comes from invert, local values are first, peaks are last
                    ii = round((float(d.time) - times[0]) / ais_code.ais_spacing_seconds)
                    img[ii,:] = np.interp(ranges, d.altitude[::-1],
                                            np.log10(d.density[::-1]),
                                            right=np.nan, left=np.nan)[::-1]

                    # This gives departures from the curve defined by the extrapolation to the first reflection point
                    # h = -1. * (d.altitude[0] - d.altitude[1]) / (np.log(d.density[0]/d.density[1]))
                    # img[ii, :] = np.log10(10.**img[ii,:] - d.density[1] * np.exp(-1. * (ranges - d.altitude[1]) / h))

                    # This gives departures from the Morgan et al model
                    sza = np.interp(d.time, self.t, self.sza)
                    # if sza < 90.:
                    # chap = mars.ChapmanLayer()
                    # # inx, = np.where(np.isfinite(img[ii,:]))
                    # # chap.fit(ranges[inx], 10**img[ii,inx[::-1]], sza)
                    # try:
                    #     chap.fit(d.altitude[::-1], d.density[::-1], np.deg2rad(sza))
                    #     model_densities = chap(ranges, np.deg2rad(sza))
                    #     print chap
                    #     print 'peak:', d.altitude[-1], d.density[-1], sza
                    # except ValueError, e:
                    #     print e
                    #     continue

                    model_densities = self.ionosphere_model(ranges, np.deg2rad(sza))
                    # img[ii, :] = np.log10(10.**img[ii,:] - model_densities)
                    img[ii, :] = 10.**img[ii,:] - model_densities[::-1]

                    # if True:
                    #      ax = plt.gca()
                    #      plt.figure()
                    #      plt.plot(np.log10(d.density), d.altitude,'k-')
                    #      if sza < 90.:
                    #          plt.plot(np.log10(model_densities), ranges,'r-')
                    #          # plt.plot(np.log10(chap(ranges)), ranges, 'r', ls='dotted')
                    #          # plt.plot(np.log10(self.ionosphere_model(ranges, np.deg2rad(sza))), ranges, 'b-')
                    #          # plt.plot(np.log10(self.ionosphere_model(ranges)), ranges, 'b', ls='dotted')
                    #      plt.xlim(2,6)
                    #      plt.sca(ax)

        extent = (self.extent[0], self.extent[1], np.nanmin(ranges), np.nanmax(ranges))
        plt.imshow(img.T, interpolation='Nearest', extent=extent,
                origin='upper',aspect='auto', cmap=matplotlib.cm.RdBu_r, vmin=-1E5,vmax=1E5)

        celsius.ylabel("alt. / km")

        old_ax = plt.gca()
        plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=[-1E5,0,1E5],format='%.1G')
        plt.ylabel(r"log $\Delta n_e$ / cm$^{-3}$")
        plt.sca(old_ax)
Пример #19
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
Пример #20
0
def plot_lat_lon_field(name=None, value='|B|', zorder=0, cmap=None,
            vmin=None, vmax=None,
            colorbar=True, cax=None, ax=None, labels=True, lims=True,
            return_data=False, label_str=None, full_range=False,
            inclination_min_b=None,
            inclination_draped_imf=0., inclination_draped_imf_orient=0.,
            snapshot_kwargs={}, data_only=False, **kwargs):
    """Plot `value` in Latitude / East Longitude.
    snapshot_kwargs go to create_snapshot if it's called.
    extra args go to imshow."""

    if name is None:
        name = mex.data_directory + 'saved_field_models/Cain_400km1deg.pck'

    if isinstance(name, str):
        print('Loading field model from %s' % name)
        with open(name, 'rb') as f:
            field_data = pickle.load(f)
    else:
        field_data = create_snapshot(name, **snapshot_kwargs)

    if ax is None:
        ax = plt.gca()
    else:
        plt.sca(ax)

    q_abs = False
    units = 'nT'
    _vmin, _vmax = 0., 50.

    if field_data['altitude'] < 200.:
        _vmax = 500.

    # TeX labels:
    label_dict = {'|B|':r'|\mathbf{B}_c|',
            'Br':r'B_r',
            'Bt':r'B_\theta',
            'Bp':r'B_\varphi',
            'Bh':r'B_H',
            'AbsInclination':r'|\delta|',
            'Inclination':r'\delta'}

    if label_str is None:
        label_str = label_dict[value]

    l_mesh_shp = field_data['longitude_mesh'].shape
    fd         = field_data['field']

    if (value == '|B|'):
        q = np.sqrt((fd[0,:].reshape(l_mesh_shp).T)**2.
                + (fd[1,:].reshape(l_mesh_shp).T)**2.
                + (fd[2,:].reshape(l_mesh_shp).T)**2.)
        q_abs = True

    elif value == 'Br':
        q = fd[0,:].reshape(l_mesh_shp).T

    elif value == 'Bt':
        q = fd[1,:].reshape(l_mesh_shp).T

    elif value == 'Bp':
        q = fd[2,:].reshape(l_mesh_shp).T

    elif value == 'Bh':
        q = np.sqrt((fd[1,:].reshape(l_mesh_shp).T)**2.
        + (fd[2,:].reshape(l_mesh_shp).T)**2.)
        q_abs = True

    elif value == 'Inclination':
        # atan ( br, b_horizontal )

        fd[1,:] += inclination_draped_imf * np.cos(np.deg2rad(inclination_draped_imf_orient))
        fd[2,:] += inclination_draped_imf * np.sin(np.deg2rad(inclination_draped_imf_orient))

        q = np.rad2deg(np.arctan2(fd[0,:].reshape(l_mesh_shp).T,
                np.sqrt((fd[1,:].reshape(l_mesh_shp).T)**2.
                        + (fd[2,:].reshape(l_mesh_shp).T)**2.)))
        _vmax = 90
        units = 'deg.'

    elif value == 'AbsInclination':
        # atan ( br, b_horizontal )

        fd[1,:] += inclination_draped_imf * np.cos(np.deg2rad(inclination_draped_imf_orient))
        fd[2,:] += inclination_draped_imf * np.sin(np.deg2rad(inclination_draped_imf_orient))

        q = np.rad2deg(np.arctan2(fd[0,:].reshape(l_mesh_shp).T,
                np.sqrt((fd[1,:].reshape(l_mesh_shp).T)**2.
                        + (fd[2,:].reshape(l_mesh_shp).T)**2.)))
        q = np.abs(q)
        _vmin = 0
        _vmax = 90
        q_abs = True
        units = 'deg.'
    else:
        raise ValueError('value "%s" not recognized' % str(value))

    if ('Inclination' in value) and (inclination_min_b is not None):
        b = np.sqrt((fd[0,:].reshape(l_mesh_shp).T)**2.
                + (fd[1,:].reshape(l_mesh_shp).T)**2.
                + (fd[2,:].reshape(l_mesh_shp).T)**2.)
        q[b < inclination_min_b] = np.nan

    if not q_abs:
        _vmin = - _vmax

    if not vmin:
        vmin = _vmin

    if not vmax:
        vmax = _vmax

    extent = (0., 360., -90, 90)

    if not cmap:
        cmap = plt.cm.RdBu_r
        if q_abs:
            cmap = plt.cm.Reds

    if data_only:
        if full_range:
            q2 = np.hstack((q, q, q))
            return q2
        return q

    if full_range:
        q2 = np.hstack((q, q, q))
        extent2 = (-360, 720., -90, 90)
        out = plt.imshow(q2, vmin=vmin, vmax=vmax, cmap=cmap, extent=extent2, **kwargs)
    else:
        out = plt.imshow(q, vmin=vmin, vmax=vmax, cmap=cmap, extent=extent, **kwargs)

    if labels:
        plt.xlabel('Longitude / deg')
        plt.ylabel('Latitude / deg')

    if lims:
        plt.xlim(0., 360.)
        plt.ylim(-90, 90)
        ax.yaxis.set_major_locator(celsius.CircularLocator())
        ax.xaxis.set_major_locator(celsius.CircularLocator())

    if colorbar:
        if not cax:
            cax = celsius.make_colorbar_cax()
        if value == 'Inclination':
            c = plt.colorbar(cax=cax, ticks=[-90, -45, 0, 45, 90])
        elif value == 'AbsInclination':
            c = plt.colorbar(cax=cax, ticks=[0, 45, 90])
        else:
            c = plt.colorbar(cax=cax)
        c.set_label(r'$%s / %s$' % (label_str, units))
        plt.sca(ax)

    if return_data:
        return q