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)
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$')
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)
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')
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))
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.)
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.)
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)
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
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.)
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)
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')
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)
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)
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)
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)
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()
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
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}$")
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)