Beispiel #1
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)
Beispiel #2
0
 def plot_r(self, ax=None, label=True, fmt='k-', **kwargs):
     if ax is None:
         ax = plt.gca()
     plt.sca(ax)
     self.generate_position()
     plt.plot(self.t, self.iau_pos[0] / mex.mars_mean_radius_km, fmt, **kwargs)
     celsius.ylabel(r'$r / R_M$')
Beispiel #3
0
    def plot_peak_altitude(self, ax=None, true_color='k',
            apparent_color='grey'):
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)

        for d in self.digitization_list:
            if d.is_invertible():
                if d.altitude.size == 0:
                    try:
                        d.invert(substitute_fp=ais_code.ne_to_fp(4.))
                    except BaseException as e:
                        print(e)
                        continue

                if apparent_color:
                    plt.plot(d.time, d.altitude[-1], marker='.',
                        ms=self.marker_size, color=apparent_color)
                alt = mex.iau_pgr_alt_lat_lon_position(float(d.time))[0]
                plt.plot(d.time,
                alt - d.traced_delay[-1] * ais_code.speed_of_light_kms / 2.,
                        marker='.', color=true_color,
                        ms=self.marker_size)
        celsius.ylabel(r'$h_{max} / km$')
        plt.ylim(0o1, 249)
Beispiel #4
0
 def plot_altitude(self, ax=None, label=True, fmt='k-', **kwargs):
     if ax is None:
         ax = plt.gca()
     plt.sca(ax)
     self.generate_position()
     plt.plot(self.t, self.iau_pos[0] - mex.mars_mean_radius_km, fmt, **kwargs)
     if label:
         celsius.ylabel('h / km')
Beispiel #5
0
 def panel(no, xn, yn, bs=True):
     plt.subplot(no, aspect="equal")
     if bs:
         plt.plot(x, y, "k--")
     plt.xlabel(xn + r"$ / R_M$")
     celsius.ylabel(yn + r"$ / R_M$", offset=off)
     plt.xlim(*lims)
     plt.ylim(*lims)
     plt.gca().add_patch(plt.Circle((0.0, 0.0), 1.0, fill=False))
Beispiel #6
0
 def plot_lat(self, ax=None, label=True, fmt='k-', **kwargs):
     if ax is None:
         ax = plt.gca()
     plt.sca(ax)
     self.make_axis_circular(ax)
     self.generate_position()
     plt.plot(self.t, self.iau_pos[1], fmt, **kwargs)
     if label:
         celsius.ylabel(r'$\lambda$')
     plt.ylim(-90., 90.)
Beispiel #7
0
 def plot_sza(self, ax=None, label=True, fmt='k-', **kwargs):
     if ax is None:
         ax = plt.gca()
     plt.sca(ax)
     self.make_axis_circular(ax)
     self.generate_position()
     plt.plot(self.t, self.sza, fmt, **kwargs)
     if label:
         celsius.ylabel(r'$SZA / deg$')
     plt.ylim(0., 180.)
Beispiel #8
0
    def plot_mod_b(self, fmt='k.', ax=None,
                    field_model=True, errors=True, field_color='blue',
                    br=True, t_offset=0., label=True, **kwargs):
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)

        sub = [d for d in self.digitization_list if np.isfinite(d.td_cyclotron)]
        if len(sub) == 0:
            print("No digitizations with marked cyclotron frequency lines")
            return

        t = np.array([d.time for d in sub])
        b = np.array([d.td_cyclotron for d in sub])
        e = np.array([d.td_cyclotron_error for d in sub])
        # print b
        # print e

        b, e = ais_code.td_to_modb(b, e)
        b *= 1.E9
        e *= 1.E9

        if errors:
            for tt,bb,ee in zip(t,b,e):
                plt.plot((tt,tt),(bb+ee,bb-ee),
                                color='lightgrey',linestyle='solid',marker='None')
                plt.plot(tt,bb,fmt,ms=self.marker_size, **kwargs)
            # plt.errorbar(t, b, e, fmt=fmt, ms=self.marker_size, **kwargs)
        else:
            plt.plot(t, b, fmt, ms=self.marker_size, **kwargs)

        if field_model:
            self.generate_position()

            if field_color is None: field_color = fmt[0]
            # b = self.quick_field_model(self.t)
            self._computed_field_model = self.field_model(self.iau_pos)
            bmag = np.sqrt(np.sum(self._computed_field_model**2., 0))
            plt.plot(self.t - t_offset,
                        bmag,
                        color=field_color, ls='-')
            if br:
                plt.plot(self.t - t_offset,
                    self._computed_field_model[0], 'r-')
                plt.plot(self.t - t_offset,
                    -1. * self._computed_field_model[0], 'r', ls='dashed')

            model_at_value = np.interp(t, self.t, bmag)
            inx = (model_at_value > 100.) & ((b / model_at_value) < 0.75)
            plt.plot(t[inx], b[inx], 'ro', mec='r', mfc='none', ms=5., mew=1.2)


        if label:
            celsius.ylabel(r'$\mathrm{|B|/nT}$')
        plt.ylim(0., 200)
Beispiel #9
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
Beispiel #10
0
 def plot_lon(self, ax=None, label=True, fmt='k-', **kwargs):
     if ax is None:
         ax = plt.gca()
     plt.sca(ax)
     self.make_axis_circular(ax)
     self.generate_position()
     v = celsius.deg_unwrap(self.iau_pos[2])
     for i in [-1,0,1]:
         plt.plot(self.t, v + i * 360, fmt, **kwargs)
     if label:
         celsius.ylabel(r'$\varphi$')
     plt.ylim(0., 360.)
Beispiel #11
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)
Beispiel #12
0
    def plot_ground_deltat(self, ax=None):
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)
        t = [d.time for d in self.digitization_list if np.isfinite(d.ground)]
        d = [d.ground for d in self.digitization_list if np.isfinite(d.ground)]
        dnew = []
        for time, delay in zip(t, d):
            mex_pos = mex.iau_mars_position(float(time))
            alt = np.sqrt(np.sum(mex_pos * mex_pos)) - mex.mars_mean_radius_km
            dnew.append( (delay - alt * 2. / ais_code.speed_of_light_kms) * 1.0E3)
        plt.plot(t, dnew)

        celsius.ylabel(r'$\Delta\tau_D$ / ms')
Beispiel #13
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)
Beispiel #14
0
    def plot_peak_density(self, fmt='k.', labels=True, ax=None, **kwargs):
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)

        for d in self.digitization_list:
            if d.is_invertible():
                if d.altitude.size == 0:
                    try:
                        d.invert(substitute_fp=ais_code.ne_to_fp(4.))
                    except BaseException as e:
                        print(e)
                        continue
                plt.plot(d.time, d.density[-1], fmt, **kwargs)

        if labels:
            celsius.ylabel(r'$n_{e,max} / cm^{-3}$')
        ax.set_yscale('log')
        plt.ylim(1E4, 5E5)
Beispiel #15
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)
Beispiel #16
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)
Beispiel #17
0
def stacked_f_plots(start=7894, finish=None, show=True,
            frequencies=[0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 2.0, 3.0]):
    gc.enable()
    if finish is None:
        finish = start + 1
    plt.close("all")
    fig = plt.figure(figsize = celsius.paper_sizes['A4'])
    orbits = list(range(start, finish))

    if len(orbits) > 1:
        show = False

    # plt.hot()

    for o in orbits:
        plt.clf()
        gc.collect()
        fname = mex.locate_data_directory() + 'marsis/ais_digitizations/%05d/%05d.dig' % ((o // 1000) * 1000, o)
        try:
            a = AISReview(o, debug=True, db_filename=fname)
        except Exception as e:
            print(e)
            continue


        n = len(frequencies) + 4
        hr = np.ones(n)
        hr[0] = 2.
        g = mpl.gridspec.GridSpec(n,1, hspace=0.1, height_ratios=hr)

        axes = []
        prev = None
        for i in range(n):
            axes.append(plt.subplot(g[i], sharex=prev))
            axes[i].set_xlim(a.extent[0], a.extent[1])
            axes[i].yaxis.set_major_locator(mpl.ticker.MaxNLocator(prune='upper', nbins=5, steps=[1,2,5,10]))
            axes[i].xaxis.set_major_locator(celsius.SpiceetLocator())
            axes[i].xaxis.set_major_formatter(celsius.SpiceetFormatter())
            prev = axes[-1]

        ax = iter(axes)

        a.plot_timeseries(ax=next(ax))
        a.plot_frequency_range(ax=next(ax), f_min=0.0, f_max=0.2)

        for i, f in enumerate(frequencies):
            a.plot_frequency_altitude(ax=next(ax), f=f)

        plt.sca(next(ax))
        b = a.quick_field_model(a.t)
        plt.plot(a.t, np.sqrt(np.sum(b**2., 0)), 'k-')
        plt.plot(a.t, b[0], 'r-')
        plt.plot(a.t, b[1], 'g-')
        plt.plot(a.t, b[2], 'b-')
        celsius.ylabel(r'$B_{SC} / nT$')

        plt.sca(next(ax))
        ion_pos = a.iau_pos
        ion_pos[0,:] = 150.0 + mex.mars_mean_radius_km
        bion = a.field_model(ion_pos)
        plt.plot(a.t, np.sqrt(np.sum(bion**2., 0)), 'k-')
        plt.plot(a.t, bion[0], 'r-')
        plt.plot(a.t, bion[1], 'g-')
        plt.plot(a.t, bion[2], 'b-')
        celsius.ylabel(r'$B_{150} / nT$')

        for i in range(n-1):
            ax = axes[i]
            plt.setp( ax.get_xticklabels(), visible=False )
            ax.xaxis.set_major_formatter(celsius.SpiceetFormatter())

        plt.annotate("Orbit %d, plot start: %s" % (o, celsius.spiceet_to_utcstr(a.extent[0])[0:14]),
            (0.5, 0.93), xycoords='figure fraction', ha='center')

        if show:
            plt.show()

        gc.collect()
Beispiel #18
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
Beispiel #19
0
    def plot_tec(self, ax=None, ss=True, verbose=False):
        if ax is None:
            ax = plt.gca()
        plt.sca(ax)

        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=False)
                if verbose:
                    print(i, d.altitude.size)
                if d.altitude.size:
                    # This tries to give an estimate of sub-solar TEC
                    # try:
                    #     c = mars.chapman.ChapmanLayer()
                    #     c.fit(d.altitude[::-1], d.density[::-1], np.interp(d.time, self.t, self.sza))
                    #     plt.plot(d.time, c.n0 * c.h* 1E3 * 1e6, 'b.', mew=0.)
                    # except ValueError, e:
                    #     print e

                    # This just estimates sub-spacecraft TEC (no SZA correction)
                    # Scale height is coarsely estimated from the height over which a drop
                    # in density by factor e is observed
                    alt_diff = d.altitude[::-1]
                    alt_diff = alt_diff - alt_diff[0]
                    density = d.density[::-1]
                    inx, = np.where(density < (density[0] / 2.71828))
                    # print '------'
                    # print density
                    # print alt_diff
                    if inx.shape[0] > 0:
                        if verbose:
                            print('>', d.time, density[0] * alt_diff[inx[0]] * 1E3 * 1e6, alt_diff[inx[0]])

                        if alt_diff[inx[0]] > 100.: continue
                        plt.plot(d.time, density[0] * alt_diff[inx[0]] * 1E3 * 1e6, 'k.')
                    # print celsius.utcstr(float(d.time)), c.n0 * c.h * 1E3 * 1e6

                    ## This was an attempt to try and get a more robust scale height, by
                    ## just looking near the peak - gives way too big values though, because
                    ## it doesn't look to the SZA, for one.
                    ## 2012-07-16
                    # s = np.argsort(d.altitude)
                    # dens = d.density[s]
                    # alt = d.altitude[s]
                    # if dens.shape[0] < 10: continue
                    # dens = dens[:10]
                    # alt = alt[:10] - alt[0]
                    # sn = np.sum(dens)
                    # b = (sn * np.sum(alt * dens * np.log(dens))
                    #         - np.sum(alt * dens) * np.sum(dens * np.log(dens)))
                    # b = b / (sn * np.sum(alt**2. * dens) - np.sum(alt * dens)**2.)
                    # plt.plot(d.time, dens[0] * b * 1E9, 'r.', mew=0.)
                    # print '---', b, -1. / b, dens[0] * -1. / b * 1E9, np.max(d.density), dens[0]
                else:
                    pass
            else:
                if verbose:
                    print(i, ' not invertible')
                pass
        if ss:
            ss_tec = mex.sub_surface.read_tec(self.start_time, self.finish_time)
            good = ss_tec['FLAG'] == 1
            plt.plot(ss_tec['EPHEMERIS_TIME'][good], ss_tec['TEC'][good], 'r.', mew=0., mec='r')

        plt.ylim(2e14, 9E16)
        plt.yscale('log')
        celsius.ylabel(r"$TEC / m^{-2}$")
Beispiel #20
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)