jroplot_data.py
759 lines
| 24.6 KiB
| text/x-python
|
PythonLexer
|
r1187 | ''' | ||
New Plots Operations | ||||
@author: juan.espinoza@jro.igp.gob.pe | ||||
''' | ||||
|
r865 | |||
import time | ||||
import datetime | ||||
|
r1062 | import numpy | ||
|
r865 | |||
|
r1187 | from schainpy.model.graphics.jroplot_base import Plot, plt | ||
|
r1062 | from schainpy.utils import log | ||
r889 | ||||
r1145 | EARTH_RADIUS = 6.3710e3 | |||
|
r1187 | |||
r1144 | def ll2xy(lat1, lon1, lat2, lon2): | |||
p = 0.017453292519943295 | ||||
|
r1187 | a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \ | ||
numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2 | ||||
r1144 | r = 12742 * numpy.arcsin(numpy.sqrt(a)) | |||
|
r1187 | theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p) | ||
* numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p)) | ||||
r1144 | theta = -theta + numpy.pi/2 | |||
return r*numpy.cos(theta), r*numpy.sin(theta) | ||||
|
r1093 | |||
|
r1187 | |||
r1145 | def km2deg(km): | |||
''' | ||||
Convert distance in km to degrees | ||||
''' | ||||
return numpy.rad2deg(km/EARTH_RADIUS) | ||||
|
r1093 | |||
|
r866 | |||
|
r1187 | class SpectraPlot(Plot): | ||
|
r1062 | ''' | ||
Plot for Spectra data | ||||
''' | ||||
|
r866 | |||
r889 | CODE = 'spc' | |||
|
r1080 | colormap = 'jro' | ||
|
r1221 | plot_name = 'Spectra' | ||
plot_type = 'pcolor' | ||||
r922 | ||||
r889 | def setup(self): | |||
|
r1062 | self.nplots = len(self.data.channels) | ||
|
r1080 | self.ncols = int(numpy.sqrt(self.nplots) + 0.9) | ||
self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9) | ||||
self.width = 3.4 * self.ncols | ||||
self.height = 3 * self.nrows | ||||
|
r1062 | self.cb_label = 'dB' | ||
|
r1080 | if self.showprofile: | ||
self.width += 0.8 * self.ncols | ||||
r889 | ||||
r1122 | self.ylabel = 'Range [km]' | |||
r889 | ||||
|
r865 | def plot(self): | ||
r889 | if self.xaxis == "frequency": | |||
|
r1062 | x = self.data.xrange[0] | ||
self.xlabel = "Frequency (kHz)" | ||||
r889 | elif self.xaxis == "time": | |||
|
r1062 | x = self.data.xrange[1] | ||
self.xlabel = "Time (ms)" | ||||
r889 | else: | |||
|
r1062 | x = self.data.xrange[2] | ||
self.xlabel = "Velocity (m/s)" | ||||
|
r1207 | if self.CODE == 'spc_moments': | ||
|
r1062 | x = self.data.xrange[2] | ||
self.xlabel = "Velocity (m/s)" | ||||
r889 | ||||
|
r1062 | self.titles = [] | ||
r889 | ||||
|
r1062 | y = self.data.heights | ||
self.y = y | ||||
z = self.data['spc'] | ||||
|
r1080 | |||
r889 | for n, ax in enumerate(self.axes): | |||
|
r1062 | noise = self.data['noise'][n][-1] | ||
|
r1207 | if self.CODE == 'spc_moments': | ||
mean = self.data['moments'][n, :, 1, :][-1] | ||||
r889 | if ax.firsttime: | |||
|
r1062 | self.xmax = self.xmax if self.xmax else numpy.nanmax(x) | ||
r889 | self.xmin = self.xmin if self.xmin else -self.xmax | |||
|
r1062 | self.zmin = self.zmin if self.zmin else numpy.nanmin(z) | ||
self.zmax = self.zmax if self.zmax else numpy.nanmax(z) | ||||
ax.plt = ax.pcolormesh(x, y, z[n].T, | ||||
|
r1080 | vmin=self.zmin, | ||
vmax=self.zmax, | ||||
cmap=plt.get_cmap(self.colormap) | ||||
) | ||||
r889 | ||||
if self.showprofile: | ||||
|
r1080 | ax.plt_profile = self.pf_axes[n].plot( | ||
self.data['rti'][n][-1], y)[0] | ||||
|
r1062 | ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y, | ||
|
r1080 | color="k", linestyle="dashed", lw=1)[0] | ||
|
r1207 | if self.CODE == 'spc_moments': | ||
|
r1062 | ax.plt_mean = ax.plot(mean, y, color='k')[0] | ||
r889 | else: | |||
|
r1062 | ax.plt.set_array(z[n].T.ravel()) | ||
r889 | if self.showprofile: | |||
|
r1062 | ax.plt_profile.set_data(self.data['rti'][n][-1], y) | ||
ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y) | ||||
|
r1207 | if self.CODE == 'spc_moments': | ||
|
r1062 | ax.plt_mean.set_data(mean, y) | ||
self.titles.append('CH {}: {:3.2f}dB'.format(n, noise)) | ||||
r922 | ||||
|
r1187 | class CrossSpectraPlot(Plot): | ||
r922 | ||||
CODE = 'cspc' | ||||
|
r1201 | colormap = 'jet' | ||
|
r1221 | plot_name = 'CrossSpectra' | ||
plot_type = 'pcolor' | ||||
r922 | zmin_coh = None | |||
zmax_coh = None | ||||
zmin_phase = None | ||||
|
r1080 | zmax_phase = None | ||
r922 | ||||
def setup(self): | ||||
|
r1062 | self.ncols = 4 | ||
self.nrows = len(self.data.pairs) | ||||
|
r1080 | self.nplots = self.nrows * 4 | ||
self.width = 3.4 * self.ncols | ||||
self.height = 3 * self.nrows | ||||
r1122 | self.ylabel = 'Range [km]' | |||
|
r1080 | self.showprofile = False | ||
r922 | ||||
def plot(self): | ||||
if self.xaxis == "frequency": | ||||
|
r1062 | x = self.data.xrange[0] | ||
self.xlabel = "Frequency (kHz)" | ||||
r922 | elif self.xaxis == "time": | |||
|
r1062 | x = self.data.xrange[1] | ||
self.xlabel = "Time (ms)" | ||||
r922 | else: | |||
|
r1062 | x = self.data.xrange[2] | ||
self.xlabel = "Velocity (m/s)" | ||||
|
r1201 | |||
|
r1062 | self.titles = [] | ||
r922 | ||||
|
r1062 | y = self.data.heights | ||
self.y = y | ||||
spc = self.data['spc'] | ||||
cspc = self.data['cspc'] | ||||
r922 | ||||
for n in range(self.nrows): | ||||
|
r1062 | noise = self.data['noise'][n][-1] | ||
pair = self.data.pairs[n] | ||||
|
r1080 | ax = self.axes[4 * n] | ||
|
r1201 | spc0 = 10.*numpy.log10(spc[pair[0]]/self.data.factor) | ||
if ax.firsttime: | ||||
self.xmax = self.xmax if self.xmax else numpy.nanmax(x) | ||||
self.xmin = self.xmin if self.xmin else -self.xmax | ||||
self.zmin = self.zmin if self.zmin else numpy.nanmin(spc) | ||||
self.zmax = self.zmax if self.zmax else numpy.nanmax(spc) | ||||
ax.plt = ax.pcolormesh(x , y , spc0.T, | ||||
|
r1062 | vmin=self.zmin, | ||
vmax=self.zmax, | ||||
cmap=plt.get_cmap(self.colormap) | ||||
|
r1201 | ) | ||
else: | ||||
ax.plt.set_array(spc0.T.ravel()) | ||||
self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise)) | ||||
r922 | ||||
|
r1080 | ax = self.axes[4 * n + 1] | ||
|
r1201 | spc1 = 10.*numpy.log10(spc[pair[1]]/self.data.factor) | ||
|
r1080 | if ax.firsttime: | ||
|
r1201 | ax.plt = ax.pcolormesh(x , y, spc1.T, | ||
r922 | vmin=self.zmin, | |||
vmax=self.zmax, | ||||
cmap=plt.get_cmap(self.colormap) | ||||
) | ||||
|
r1201 | else: | ||
ax.plt.set_array(spc1.T.ravel()) | ||||
self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise)) | ||||
|
r1080 | out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]]) | ||
|
r1062 | coh = numpy.abs(out) | ||
|
r1080 | phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi | ||
ax = self.axes[4 * n + 2] | ||||
if ax.firsttime: | ||||
|
r1062 | ax.plt = ax.pcolormesh(x, y, coh.T, | ||
vmin=0, | ||||
vmax=1, | ||||
cmap=plt.get_cmap(self.colormap_coh) | ||||
) | ||||
else: | ||||
ax.plt.set_array(coh.T.ravel()) | ||||
|
r1080 | self.titles.append( | ||
'Coherence Ch{} * Ch{}'.format(pair[0], pair[1])) | ||||
|
r1201 | |||
|
r1080 | ax = self.axes[4 * n + 3] | ||
|
r1062 | if ax.firsttime: | ||
ax.plt = ax.pcolormesh(x, y, phase.T, | ||||
vmin=-180, | ||||
vmax=180, | ||||
|
r1201 | cmap=plt.get_cmap(self.colormap_phase) | ||
|
r1062 | ) | ||
else: | ||||
ax.plt.set_array(phase.T.ravel()) | ||||
self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1])) | ||||
|
r1080 | |||
|
r866 | |||
|
r1207 | class SpectralMomentsPlot(SpectraPlot): | ||
|
r1062 | ''' | ||
|
r1207 | Plot for Spectral Moments | ||
|
r1062 | ''' | ||
|
r1207 | CODE = 'spc_moments' | ||
|
r1062 | colormap = 'jro' | ||
|
r1221 | plot_name = 'SpectralMoments' | ||
plot_type = 'pcolor' | ||||
|
r1062 | |||
|
r1187 | class RTIPlot(Plot): | ||
|
r1062 | ''' | ||
Plot for RTI data | ||||
''' | ||||
r889 | ||||
CODE = 'rti' | ||||
colormap = 'jro' | ||||
|
r1221 | plot_name = 'RTI' | ||
plot_type = 'pcolorbuffer' | ||||
r889 | ||||
def setup(self): | ||||
|
r1062 | self.xaxis = 'time' | ||
|
r1080 | self.ncols = 1 | ||
|
r1062 | self.nrows = len(self.data.channels) | ||
self.nplots = len(self.data.channels) | ||||
r1122 | self.ylabel = 'Range [km]' | |||
|
r1062 | self.cb_label = 'dB' | ||
|
r1080 | self.titles = ['{} Channel {}'.format( | ||
self.CODE.upper(), x) for x in range(self.nrows)] | ||||
r922 | ||||
|
r866 | def plot(self): | ||
|
r1187 | self.x = self.data.times | ||
|
r1062 | self.y = self.data.heights | ||
self.z = self.data[self.CODE] | ||||
self.z = numpy.ma.masked_invalid(self.z) | ||||
|
r865 | |||
|
r1119 | if self.decimation is None: | ||
x, y, z = self.fill_gaps(self.x, self.y, self.z) | ||||
else: | ||||
|
r1080 | x, y, z = self.fill_gaps(*self.decimate()) | ||
|
r1119 | |||
|
r1187 | for n, ax in enumerate(self.axes): | ||
|
r1062 | self.zmin = self.zmin if self.zmin else numpy.min(self.z) | ||
self.zmax = self.zmax if self.zmax else numpy.max(self.z) | ||||
|
r1080 | if ax.firsttime: | ||
|
r1062 | ax.plt = ax.pcolormesh(x, y, z[n].T, | ||
|
r1080 | vmin=self.zmin, | ||
vmax=self.zmax, | ||||
cmap=plt.get_cmap(self.colormap) | ||||
) | ||||
|
r1062 | if self.showprofile: | ||
|
r1080 | ax.plot_profile = self.pf_axes[n].plot( | ||
self.data['rti'][n][-1], self.y)[0] | ||||
|
r1062 | ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y, | ||
color="k", linestyle="dashed", lw=1)[0] | ||||
else: | ||||
ax.collections.remove(ax.collections[0]) | ||||
ax.plt = ax.pcolormesh(x, y, z[n].T, | ||||
vmin=self.zmin, | ||||
vmax=self.zmax, | ||||
cmap=plt.get_cmap(self.colormap) | ||||
|
r1080 | ) | ||
|
r1062 | if self.showprofile: | ||
ax.plot_profile.set_data(self.data['rti'][n][-1], self.y) | ||||
|
r1080 | ax.plot_noise.set_data(numpy.repeat( | ||
self.data['noise'][n][-1], len(self.y)), self.y) | ||||
|
r964 | |||
r889 | ||||
|
r1187 | class CoherencePlot(RTIPlot): | ||
|
r1062 | ''' | ||
Plot for Coherence data | ||||
''' | ||||
r889 | ||||
CODE = 'coh' | ||||
|
r1221 | plot_name = 'Coherence' | ||
r889 | ||||
def setup(self): | ||||
|
r1062 | self.xaxis = 'time' | ||
r889 | self.ncols = 1 | |||
|
r1062 | self.nrows = len(self.data.pairs) | ||
self.nplots = len(self.data.pairs) | ||||
r1122 | self.ylabel = 'Range [km]' | |||
|
r1062 | if self.CODE == 'coh': | ||
self.cb_label = '' | ||||
|
r1080 | self.titles = [ | ||
'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] | ||||
r889 | else: | |||
|
r1062 | self.cb_label = 'Degrees' | ||
|
r1080 | self.titles = [ | ||
'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] | ||||
r889 | ||||
|
r1062 | |||
|
r1187 | class PhasePlot(CoherencePlot): | ||
|
r1062 | ''' | ||
Plot for Phase map data | ||||
''' | ||||
CODE = 'phase' | ||||
colormap = 'seismic' | ||||
|
r1221 | plot_name = 'Phase' | ||
r889 | ||||
|
r865 | |||
|
r1187 | class NoisePlot(Plot): | ||
|
r1062 | ''' | ||
Plot for noise | ||||
''' | ||||
r907 | CODE = 'noise' | |||
|
r1221 | plot_name = 'Noise' | ||
plot_type = 'scatterbuffer' | ||||
r907 | ||||
def setup(self): | ||||
|
r1062 | self.xaxis = 'time' | ||
r907 | self.ncols = 1 | |||
self.nrows = 1 | ||||
|
r1062 | self.nplots = 1 | ||
r907 | self.ylabel = 'Intensity [dB]' | |||
self.titles = ['Noise'] | ||||
|
r1062 | self.colorbar = False | ||
r907 | ||||
def plot(self): | ||||
|
r1187 | x = self.data.times | ||
xmin = self.data.min_time | ||||
|
r1080 | xmax = xmin + self.xrange * 60 * 60 | ||
|
r1062 | Y = self.data[self.CODE] | ||
|
r1080 | |||
|
r1062 | if self.axes[0].firsttime: | ||
for ch in self.data.channels: | ||||
y = Y[ch] | ||||
self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch)) | ||||
r907 | plt.legend() | |||
else: | ||||
|
r1062 | for ch in self.data.channels: | ||
y = Y[ch] | ||||
self.axes[0].lines[ch].set_data(x, y) | ||||
|
r1080 | |||
|
r1062 | self.ymin = numpy.nanmin(Y) - 5 | ||
self.ymax = numpy.nanmax(Y) + 5 | ||||
r922 | ||||
r907 | ||||
|
r1187 | class SnrPlot(RTIPlot): | ||
|
r1062 | ''' | ||
Plot for SNR Data | ||||
''' | ||||
|
r898 | CODE = 'snr' | ||
r922 | colormap = 'jet' | |||
|
r1221 | plot_name = 'SNR' | ||
r889 | ||||
|
r1062 | |||
|
r1187 | class DopplerPlot(RTIPlot): | ||
|
r1062 | ''' | ||
Plot for DOPPLER Data | ||||
''' | ||||
|
r898 | CODE = 'dop' | ||
colormap = 'jet' | ||||
|
r1221 | plot_name = 'Doppler' | ||
r889 | ||||
r922 | ||||
|
r1187 | class SkyMapPlot(Plot): | ||
|
r1062 | ''' | ||
Plot for meteors detection data | ||||
''' | ||||
|
r937 | |||
|
r1095 | CODE = 'param' | ||
|
r937 | |||
def setup(self): | ||||
self.ncols = 1 | ||||
self.nrows = 1 | ||||
self.width = 7.2 | ||||
self.height = 7.2 | ||||
|
r1095 | self.nplots = 1 | ||
|
r937 | self.xlabel = 'Zonal Zenith Angle (deg)' | ||
self.ylabel = 'Meridional Zenith Angle (deg)' | ||||
|
r1095 | self.polar = True | ||
self.ymin = -180 | ||||
self.ymax = 180 | ||||
self.colorbar = False | ||||
|
r937 | |||
def plot(self): | ||||
|
r1098 | arrayParameters = numpy.concatenate(self.data['param']) | ||
|
r1080 | error = arrayParameters[:, -1] | ||
|
r937 | indValid = numpy.where(error == 0)[0] | ||
|
r1080 | finalMeteor = arrayParameters[indValid, :] | ||
finalAzimuth = finalMeteor[:, 3] | ||||
finalZenith = finalMeteor[:, 4] | ||||
|
r937 | |||
|
r1080 | x = finalAzimuth * numpy.pi / 180 | ||
|
r937 | y = finalZenith | ||
|
r1095 | ax = self.axes[0] | ||
if ax.firsttime: | ||||
|
r1098 | ax.plot = ax.plot(x, y, 'bo', markersize=5)[0] | ||
|
r937 | else: | ||
|
r1095 | ax.plot.set_data(x, y) | ||
|
r937 | |||
|
r1187 | dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S') | ||
dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S') | ||||
|
r937 | title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1, | ||
dt2, | ||||
len(x)) | ||||
|
r1095 | self.titles[0] = title | ||
|
r1062 | |||
|
r1080 | |||
|
r1187 | class ParametersPlot(RTIPlot): | ||
|
r1062 | ''' | ||
Plot for data_param object | ||||
''' | ||||
CODE = 'param' | ||||
colormap = 'seismic' | ||||
|
r1221 | plot_name = 'Parameters' | ||
|
r1062 | |||
def setup(self): | ||||
self.xaxis = 'time' | ||||
self.ncols = 1 | ||||
self.nrows = self.data.shape(self.CODE)[0] | ||||
self.nplots = self.nrows | ||||
if self.showSNR: | ||||
self.nrows += 1 | ||||
r1065 | self.nplots += 1 | |||
|
r1080 | |||
r1122 | self.ylabel = 'Height [km]' | |||
r1105 | if not self.titles: | |||
self.titles = self.data.parameters \ | ||||
|
r1167 | if self.data.parameters else ['Param {}'.format(x) for x in range(self.nrows)] | ||
r1105 | if self.showSNR: | |||
self.titles.append('SNR') | ||||
|
r1062 | |||
def plot(self): | ||||
|
r1080 | self.data.normalize_heights() | ||
|
r1187 | self.x = self.data.times | ||
|
r1062 | self.y = self.data.heights | ||
|
r1080 | if self.showSNR: | ||
|
r1062 | self.z = numpy.concatenate( | ||
(self.data[self.CODE], self.data['snr']) | ||||
) | ||||
else: | ||||
self.z = self.data[self.CODE] | ||||
self.z = numpy.ma.masked_invalid(self.z) | ||||
|
r1119 | if self.decimation is None: | ||
x, y, z = self.fill_gaps(self.x, self.y, self.z) | ||||
else: | ||||
|
r1062 | x, y, z = self.fill_gaps(*self.decimate()) | ||
|
r1119 | |||
for n, ax in enumerate(self.axes): | ||||
|
r1187 | |||
|
r1093 | self.zmax = self.zmax if self.zmax is not None else numpy.max( | ||
self.z[n]) | ||||
self.zmin = self.zmin if self.zmin is not None else numpy.min( | ||||
self.z[n]) | ||||
|
r1062 | if ax.firsttime: | ||
if self.zlimits is not None: | ||||
self.zmin, self.zmax = self.zlimits[n] | ||||
|
r1093 | |||
ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n], | ||||
|
r1062 | vmin=self.zmin, | ||
vmax=self.zmax, | ||||
cmap=self.cmaps[n] | ||||
|
r1080 | ) | ||
|
r1062 | else: | ||
if self.zlimits is not None: | ||||
self.zmin, self.zmax = self.zlimits[n] | ||||
ax.collections.remove(ax.collections[0]) | ||||
|
r1093 | ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n], | ||
|
r1062 | vmin=self.zmin, | ||
vmax=self.zmax, | ||||
cmap=self.cmaps[n] | ||||
|
r1080 | ) | ||
|
r1062 | |||
|
r1093 | |||
|
r1187 | class OutputPlot(ParametersPlot): | ||
|
r1062 | ''' | ||
Plot data_output object | ||||
''' | ||||
CODE = 'output' | ||||
r1065 | colormap = 'seismic' | |||
|
r1221 | plot_name = 'Output' | ||
r1137 | ||||
|
r1187 | class PolarMapPlot(Plot): | ||
r1137 | ''' | |||
|
r1187 | Plot for weather radar | ||
r1137 | ''' | |||
CODE = 'param' | ||||
colormap = 'seismic' | ||||
def setup(self): | ||||
self.ncols = 1 | ||||
self.nrows = 1 | ||||
self.width = 9 | ||||
self.height = 8 | ||||
r1145 | self.mode = self.data.meta['mode'] | |||
r1137 | if self.channels is not None: | |||
self.nplots = len(self.channels) | ||||
self.nrows = len(self.channels) | ||||
else: | ||||
self.nplots = self.data.shape(self.CODE)[0] | ||||
self.nrows = self.nplots | ||||
|
r1167 | self.channels = list(range(self.nplots)) | ||
r1145 | if self.mode == 'E': | |||
self.xlabel = 'Longitude' | ||||
self.ylabel = 'Latitude' | ||||
r1141 | else: | |||
self.xlabel = 'Range (km)' | ||||
self.ylabel = 'Height (km)' | ||||
r1137 | self.bgcolor = 'white' | |||
r1141 | self.cb_labels = self.data.meta['units'] | |||
r1145 | self.lat = self.data.meta['latitude'] | |||
self.lon = self.data.meta['longitude'] | ||||
|
r1187 | self.xmin, self.xmax = float( | ||
km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon) | ||||
self.ymin, self.ymax = float( | ||||
km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat) | ||||
r1145 | # self.polar = True | |||
|
r1187 | def plot(self): | ||
r1137 | for n, ax in enumerate(self.axes): | |||
data = self.data['param'][self.channels[n]] | ||||
|
r1187 | |||
zeniths = numpy.linspace( | ||||
0, self.data.meta['max_range'], data.shape[1]) | ||||
if self.mode == 'E': | ||||
r1141 | azimuths = -numpy.radians(self.data.heights)+numpy.pi/2 | |||
r, theta = numpy.meshgrid(zeniths, azimuths) | ||||
|
r1187 | x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin( | ||
theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])) | ||||
r1145 | x = km2deg(x) + self.lon | |||
y = km2deg(y) + self.lat | ||||
r1141 | else: | |||
azimuths = numpy.radians(self.data.heights) | ||||
r, theta = numpy.meshgrid(zeniths, azimuths) | ||||
x, y = r*numpy.cos(theta), r*numpy.sin(theta) | ||||
r1137 | self.y = zeniths | |||
if ax.firsttime: | ||||
if self.zlimits is not None: | ||||
self.zmin, self.zmax = self.zlimits[n] | ||||
|
r1187 | ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)), | ||
x, y, numpy.ma.array(data, mask=numpy.isnan(data)), | ||||
vmin=self.zmin, | ||||
vmax=self.zmax, | ||||
cmap=self.cmaps[n]) | ||||
r1137 | else: | |||
if self.zlimits is not None: | ||||
self.zmin, self.zmax = self.zlimits[n] | ||||
ax.collections.remove(ax.collections[0]) | ||||
|
r1187 | ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)), | ||
x, y, numpy.ma.array(data, mask=numpy.isnan(data)), | ||||
vmin=self.zmin, | ||||
vmax=self.zmax, | ||||
cmap=self.cmaps[n]) | ||||
r1137 | ||||
r1145 | if self.mode == 'A': | |||
r1141 | continue | |||
|
r1187 | |||
r1147 | # plot district names | |||
f = open('/data/workspace/schain_scripts/distrito.csv') | ||||
r1141 | for line in f: | |||
r1144 | label, lon, lat = [s.strip() for s in line.split(',') if s] | |||
lat = float(lat) | ||||
|
r1187 | lon = float(lon) | ||
r1147 | # ax.plot(lon, lat, '.b', ms=2) | |||
|
r1187 | ax.text(lon, lat, label.decode('utf8'), ha='center', | ||
va='bottom', size='8', color='black') | ||||
r1147 | # plot limites | |||
|
r1187 | limites = [] | ||
r1147 | tmp = [] | |||
for line in open('/data/workspace/schain_scripts/lima.csv'): | ||||
if '#' in line: | ||||
if tmp: | ||||
limites.append(tmp) | ||||
tmp = [] | ||||
continue | ||||
values = line.strip().split(',') | ||||
tmp.append((float(values[0]), float(values[1]))) | ||||
for points in limites: | ||||
|
r1187 | ax.add_patch( | ||
Polygon(points, ec='k', fc='none', ls='--', lw=0.5)) | ||||
r1147 | ||||
# plot Cuencas | ||||
for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'): | ||||
f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca)) | ||||
values = [line.strip().split(',') for line in f] | ||||
points = [(float(s[0]), float(s[1])) for s in values] | ||||
ax.add_patch(Polygon(points, ec='b', fc='none')) | ||||
# plot grid | ||||
for r in (15, 30, 45, 60): | ||||
|
r1187 | ax.add_artist(plt.Circle((self.lon, self.lat), | ||
km2deg(r), color='0.6', fill=False, lw=0.2)) | ||||
r1147 | ax.text( | |||
self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180), | ||||
self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180), | ||||
|
r1187 | '{}km'.format(r), | ||
r1147 | ha='center', va='bottom', size='8', color='0.6', weight='heavy') | |||
|
r1187 | |||
r1145 | if self.mode == 'E': | |||
r1141 | title = 'El={}$^\circ$'.format(self.data.meta['elevation']) | |||
r1145 | label = 'E{:02d}'.format(int(self.data.meta['elevation'])) | |||
r1141 | else: | |||
title = 'Az={}$^\circ$'.format(self.data.meta['azimuth']) | ||||
r1145 | label = 'A{:02d}'.format(int(self.data.meta['azimuth'])) | |||
r1141 | ||||
|
r1187 | self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels] | ||
self.titles = ['{} {}'.format( | ||||
self.data.parameters[x], title) for x in self.channels] | ||||
|
r1202 | |||
|
r1209 | |||
|
r1202 | class ScopePlot(Plot): | ||
''' | ||||
Plot for Scope | ||||
''' | ||||
CODE = 'scope' | ||||
|
r1221 | plot_name = 'Scope' | ||
plot_type = 'scatter' | ||||
|
r1202 | |||
def setup(self): | ||||
self.xaxis = 'Range (Km)' | ||||
self.ncols = 1 | ||||
self.nrows = 1 | ||||
self.nplots = 1 | ||||
self.ylabel = 'Intensity [dB]' | ||||
self.titles = ['Scope'] | ||||
self.colorbar = False | ||||
colspan = 3 | ||||
rowspan = 1 | ||||
def plot_iq(self, x, y, channelIndexList, thisDatetime, wintitle): | ||||
yreal = y[channelIndexList,:].real | ||||
yimag = y[channelIndexList,:].imag | ||||
title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y")) | ||||
self.xlabel = "Range (Km)" | ||||
self.ylabel = "Intensity - IQ" | ||||
self.y = yreal | ||||
self.x = x | ||||
self.xmin = min(x) | ||||
self.xmax = max(x) | ||||
self.titles[0] = title | ||||
for i,ax in enumerate(self.axes): | ||||
title = "Channel %d" %(i) | ||||
if ax.firsttime: | ||||
ax.plt_r = ax.plot(x, yreal[i,:], color='b')[0] | ||||
ax.plt_i = ax.plot(x, yimag[i,:], color='r')[0] | ||||
else: | ||||
#pass | ||||
ax.plt_r.set_data(x, yreal[i,:]) | ||||
ax.plt_i.set_data(x, yimag[i,:]) | ||||
def plot_power(self, x, y, channelIndexList, thisDatetime, wintitle): | ||||
y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:]) | ||||
yreal = y.real | ||||
self.y = yreal | ||||
title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y")) | ||||
self.xlabel = "Range (Km)" | ||||
self.ylabel = "Intensity" | ||||
self.xmin = min(x) | ||||
self.xmax = max(x) | ||||
self.titles[0] = title | ||||
for i,ax in enumerate(self.axes): | ||||
title = "Channel %d" %(i) | ||||
ychannel = yreal[i,:] | ||||
if ax.firsttime: | ||||
ax.plt_r = ax.plot(x, ychannel)[0] | ||||
else: | ||||
#pass | ||||
ax.plt_r.set_data(x, ychannel) | ||||
def plot(self): | ||||
if self.channels: | ||||
channels = self.channels | ||||
else: | ||||
channels = self.data.channels | ||||
thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]) | ||||
scope = self.data['scope'] | ||||
if self.data.flagDataAsBlock: | ||||
for i in range(self.data.nProfiles): | ||||
wintitle1 = " [Profile = %d] " %i | ||||
if self.type == "power": | ||||
self.plot_power(self.data.heights, | ||||
scope[:,i,:], | ||||
channels, | ||||
thisDatetime, | ||||
wintitle1 | ||||
) | ||||
if self.type == "iq": | ||||
self.plot_iq(self.data.heights, | ||||
scope[:,i,:], | ||||
channels, | ||||
thisDatetime, | ||||
wintitle1 | ||||
) | ||||
else: | ||||
wintitle = " [Profile = %d] " %self.data.profileIndex | ||||
if self.type == "power": | ||||
self.plot_power(self.data.heights, | ||||
scope, | ||||
channels, | ||||
thisDatetime, | ||||
wintitle | ||||
) | ||||
if self.type == "iq": | ||||
self.plot_iq(self.data.heights, | ||||
scope, | ||||
channels, | ||||
thisDatetime, | ||||
wintitle | ||||
) | ||||