def geolocate_radar_fov(rad): """ Geolocate each range cell """ r = radar(code=rad) s = r.sites[0] f = fov(site=s) blen, glen = len(f.beams), len(f.gates) if glen >= 110: glen = 110 glat, glon, azm = np.zeros((blen, glen)), np.zeros((blen, glen)), np.zeros( (blen, glen)) for i, b in enumerate(f.beams): for j, g in enumerate(f.gates): if j < 110: glat[i, j], glon[i, j] = f.latCenter[b, g], f.lonCenter[b, g] d = utils.geoPack.calcDistPnt(f.latFull[b, g], f.lonFull[b, g], 300, distLat=f.latFull[b, g + 1], distLon=f.lonFull[b, g + 1], distAlt=300) azm[i, j] = d["az"] fname = "data/sim/{rad}.geolocate.data.nc".format(rad=rad) rootgrp = Dataset(fname, "w", format="NETCDF4") rootgrp.description = """ Fitacf++ : Geolocated points for each range cells. """ rootgrp.history = "Created " + time.ctime(time.time()) rootgrp.source = "AMGeO - SD data processing" rootgrp.createDimension("nbeam", blen) rootgrp.createDimension("ngate", glen) beam = rootgrp.createVariable("beams", "i1", ("nbeam", )) gate = rootgrp.createVariable("gates", "i1", ("ngate", )) beam[:], gate[:], = f.beams, f.gates[:glen] _glat = rootgrp.createVariable("lat", "f4", ("nbeam", "ngate")) _glon = rootgrp.createVariable("lon", "f4", ("nbeam", "ngate")) _azm = rootgrp.createVariable("azm", "f4", ("nbeam", "ngate")) _glat[:], _glon[:], _azm[:] = glat, glon, azm _glat.description = "Geographic latitude of range cell" _glon.description = "Geographic longitude of range cell" _azm.description = "Azimuthal angle ray vector bearing" _glat.units = "Deg(o)" _glon.units = "Deg(o)" _azm.units = "Deg(o)" rootgrp.close() os.system("gzip " + fname) return
def geolocate_radar_fov(rad): """ Geolocate each range cell """ r = radar(code=rad) s = r.sites[0] f = fov(site=s) blen, glen = len(f.beams), len(f.gates) glat, glon = np.zeros((blen, glen)), np.zeros((blen, glen)) for i,b in enumerate(f.beams): for j,g in enumerate(f.gates): glat[i,j], glon[i,j] = f.latCenter[b,g], f.lonCenter[b,g] fname = "data/sim/{rad}.geolocate.data.nc".format(rad=rad) rootgrp = Dataset(fname, "w") rootgrp.description = """ SuperDARN Clustering - Geolocated points for each range cells. """ rootgrp.history = "Created " + time.ctime(time.time()) rootgrp.source = "SuperDARN Clustering" rootgrp.createDimension("nbeam", blen) rootgrp.createDimension("ngate", glen) _glat = rootgrp.createVariable("geo_lat","f8",("nbeam","ngate")) _glon = rootgrp.createVariable("geo_lon","f8",("nbeam","ngate")) _glat[:], _glon[:] = glat, glon rootgrp.close() os.system("gzip "+fname) return
def overlayFov(mapObj, codes=None, ids=None, names=None, dateTime=None, plot_all=False, maxGate=None, rangeLimits=None, beamLimits=None, model='IS', fov_dir='front', fovColor=None, fovAlpha=0.2, beams=None, beamsColors=None, hemi=None, fovObj=None, zorder=2, lineColor='k', lineWidth=1): """ Overlay FoV position(s) on map Parameters ---------- mapObj : mapObj or Basemap object Object on which to overplot the radar position(s) codes : Optional[list] List of radar 3-letter codes to plot ids : Optional[list] List of radar IDs to plot names : Optional[list] List of radar names to plot dateTime : Optional[datetime.datetime] Object to use for the FOV. Default: uses mapObj.dateTime plot_all : Optional[boolean] Set to true to plot all the radars (active ones) maxGate : Optional[int] Maximum number of gates to be plotted. Defaults to hdw.dat information. rangeLimits : Optional[list, int] Plot only between the range gates specified. beamLimits : Optional[2-element list] Plot only between the beams specified. model : Optional[str] IS : standard ionospheric scatter projection model (default) GS : standard ground scatter projection model S : standard projection model E1 : for Chisham E-region 1/2-hop ionospheric projection model F1 : for Chisham F-region 1/2-hop ionospheric projection model F3 : for Chisham F-region 1 1/2-hop ionospheric projection model C : Chisham projection model None : if you trust your elevation or altitude values fov_dir : Optional[str] Field of view direction ('front' or 'back'). Value in fov object will overwrite this choice. Default='front' zorder : Optional[int] The overlay order number lineColor : Optional[str] FoV contour line color. Default is 'k' for black. lineWidth : Optional[int] FoV contour line width fovColor : Optional[str] Field of view fill color fovAlpha : Optional[str] Field of view fill color transparency fovObj : Optional[fov object] See pydarn.radar.radFov.fov hemi : Optional[str] 'north' or 'south', ignore radars from the other hemisphere beams : Optional[int] hightlight specified beams beamsColors : Optional[str] colors of the hightlighted beams Returns ------- None Example ------- import pydarn, utils # Width and height give the window size in meters width = 111e3*40 m=utils.plotUtils.mapObj(width=width,height=width,lat_0=50.,lon_0=-95.) # Plot radar position and code pydarn.plot.overlayRadar(m, fontSize=12, codes='bks') # Plot radar fov pydarn.plot.overlayFov(m, codes='bks', maxGate=75, beams=[0,4,7,8,23]) written by Sebastien, 2012-09 """ from davitpy.pydarn.radar import network from davitpy.pydarn.radar.radFov import fov from datetime import datetime as dt from datetime import timedelta import matplotlib.cm as cm from numpy import transpose, ones, concatenate, vstack, shape import numpy as np from matplotlib.patches import Polygon from pylab import gca # Set dateTime. if dateTime is not None: if hasattr(mapObj, 'dateTime') and dateTime != mapObj.dateTime: logging.warning("dateTime is " + str(dateTime) + ", not mapObj.dateTime " + str(mapObj.dateTime)) else: dateTime = mapObj.dateTime # Load radar structure network_obj = network() # If all radars are to be plotted, create the list if plot_all: codes = network_obj.getAllCodes(datetime=dateTime, hemi=hemi) # Define how the radars to be plotted are identified (code, id or name) if codes: rad_input = {'meth': 'code', 'vals': codes} elif ids: rad_input = {'meth': 'id', 'vals': ids} elif names: rad_input = {'meth': 'name', 'vals': names} else: logging.error('No radars to plot') return # Check if radars is given as a list if not isinstance(rad_input['vals'], list): rad_input['vals'] = [rad_input['vals']] nradars = len(rad_input['vals']) # Initialize the line color for the field of view lcolor = lineColor # iterates through radars to be plotted for ir in xrange(nradars): # Get field of view coordinates if fovObj is None: rad = network_obj.getRadarBy(rad_input['vals'][ir], rad_input['meth']) if not rad: continue site = rad.getSiteByDate(dateTime) if not site: continue # Set number of gates to be plotted egate = site.maxgate - 1 if not maxGate else maxGate ebeam = site.maxbeam if not hasattr(mapObj, 'coords'): rad_fov = fov(site=site, ngates=egate + 1, model=model, fov_dir=fov_dir) else: rad_fov = fov(site=site, ngates=egate + 1, coords=mapObj.coords, model=model, date_time=dateTime, fov_dir=fov_dir) else: rad_fov = fovObj egate = len(fovObj.gates) ebeam = len(fovObj.beams) model = fovObj.model fov_dir = fovObj.fov_dir if rangeLimits is not None: sgate = rangeLimits[0] egate = rangeLimits[1] else: sgate = 0 if beamLimits is not None: sbeam = beamLimits[0] ebeam = beamLimits[1] else: sbeam = 0 if model == 'GS': # Ground scatter model is not defined for close in rangegates. # np.nan will be returned for these gates. # Set sGate >= to the first rangegate that has real values. not_finite = np.logical_not(np.isfinite(rad_fov.lonFull)) grid = np.tile(np.arange(rad_fov.lonFull.shape[1]), (rad_fov.lonFull.shape[0], 1)) grid[not_finite] = 999999 tmp_sGate = (np.min(grid, axis=1)).max() if tmp_sGate > sgate: sgate = tmp_sGate # Get radar coordinates in map projection if hasattr(mapObj, 'coords'): x, y = mapObj(rad_fov.lonFull, rad_fov.latFull, coords=rad_fov.coords) else: x, y = mapObj(rad_fov.lonFull, rad_fov.latFull) # Plot field of view # Create contour contour_x = concatenate((x[sbeam, sgate:egate], x[sbeam:ebeam, egate], x[ebeam, egate:sgate:-1], x[ebeam:sbeam:-1, sgate])) contour_y = concatenate((y[sbeam, sgate:egate], y[sbeam:ebeam, egate], y[ebeam, egate:sgate:-1], y[ebeam:sbeam:-1, sgate])) # Set the color if a different color has been specified for each radar if isinstance(lineColor, list) and len(lineColor) > ir: lcolor = lineColor[ir] # Plot contour mapObj.plot(contour_x, contour_y, color=lcolor, zorder=zorder, linewidth=lineWidth) # Field of view fill if fovColor: contour = transpose(vstack((contour_x, contour_y))) patch = Polygon(contour, color=fovColor, alpha=fovAlpha, zorder=zorder) mapObj.ax.add_patch(patch) # Beams fill if beams: try: [b for b in beams] except: beams = [beams] for ib in beams: if not (0 <= ib <= x.shape[0]): continue if not beamsColors: bcol_rgb = ib / float(x.shape[0]) bcol = (bcol_rgb / 2., bcol_rgb, 1) else: bcol = beamsColors[beams.index(ib)] contour_x = concatenate((x[ib, sgate:egate + 1], x[ib:ib + 2, egate], x[ib + 1, egate:sgate:-1], x[ib + 1:ib - 1:-1, sgate])) contour_y = concatenate((y[ib, sgate:egate + 1], y[ib:ib + 2, egate], y[ib + 1, egate:sgate:-1], y[ib + 1:ib - 1:-1, sgate])) contour = transpose(vstack((contour_x, contour_y))) patch = Polygon(contour, color=bcol, alpha=.4, zorder=zorder) mapObj.ax.add_patch(patch) return
def overlayFov(mapObj, codes=None, ids=None, names=None, dateTime=None, plot_all=False, maxGate=None, rangeLimits=None, beamLimits=None, model='IS', fov_dir='front', fovColor=None, fovAlpha=0.2, beams=None, beamsColors=None, hemi=None, fovObj=None, zorder=2, lineColor='k', lineWidth=1): """ Overlay FoV position(s) on map Parameters ---------- mapObj : mapObj or Basemap object Object on which to overplot the radar position(s) codes : Optional[list] List of radar 3-letter codes to plot ids : Optional[list] List of radar IDs to plot names : Optional[list] List of radar names to plot dateTime : Optional[datetime.datetime] Object to use for the FOV. Default: uses mapObj.dateTime plot_all : Optional[boolean] Set to true to plot all the radars (active ones) maxGate : Optional[int] Maximum number of gates to be plotted. Defaults to hdw.dat information. rangeLimits : Optional[list, int] Plot only between the range gates specified. beamLimits : Optional[2-element list] Plot only between the beams specified. model : Optional[str] 'IS for ionopsheric scatter projection model (default), 'GS' for ground scatter projection model, None if you are really confident in your elevation or altitude values fov_dir : Optional[str] Field of view direction ('front' or 'back'). Default='front' zorder : Optional[int] The overlay order number lineColor : Optional[str] FoV contour line color. Default is 'k' for black. lineWidth : Optional[int] FoV contour line width fovColor : Optional[str] Field of view fill color fovAlpha : Optional[str] Field of view fill color transparency fovObj : Optional[fov object] See pydarn.radar.radFov.fov hemi : Optional[str] 'north' or 'south', ignore radars from the other hemisphere beams : Optional[int] hightlight specified beams beamsColors : Optional[str] colors of the hightlighted beams Returns ------- None Example ------- import pydarn, utils # Width and height give the window size in meters width = 111e3*40 m=utils.plotUtils.mapObj(width=width,height=width,lat_0=50.,lon_0=-95.) # Plot radar position and code pydarn.plot.overlayRadar(m, fontSize=12, codes='bks') # Plot radar fov pydarn.plot.overlayFov(m, codes='bks', maxGate=75, beams=[0,4,7,8,23]) written by Sebastien, 2012-09 """ from davitpy.pydarn.radar import network from davitpy.pydarn.radar.radFov import fov from datetime import datetime as dt from datetime import timedelta import matplotlib.cm as cm from numpy import transpose, ones, concatenate, vstack, shape import numpy as np from matplotlib.patches import Polygon from pylab import gca # Set dateTime. if dateTime is not None: if hasattr(mapObj, 'dateTime') and dateTime != mapObj.dateTime: logging.warning("dateTime is " + str(dateTime) + \ ", not mapObj.dateTime " + str(mapObj.dateTime)) else: dateTime = mapObj.dateTime # Load radar structure network_obj = network() # If all radars are to be plotted, create the list if plot_all: codes = network_obj.getAllCodes(datetime=dateTime, hemi=hemi) # Define how the radars to be plotted are identified (code, id or name) if codes: rad_input = {'meth': 'code', 'vals': codes} elif ids: rad_input = {'meth': 'id', 'vals': ids} elif names: rad_input = {'meth': 'name', 'vals': names} else: logging.error('No radars to plot') return # Check if radars is given as a list if not isinstance(rad_input['vals'], list): rad_input['vals'] = [rad_input['vals']] nradars = len(rad_input['vals']) # Initialize the line color for the field of view lcolor = lineColor # iterates through radars to be plotted for ir in xrange(nradars): # Get field of view coordinates if(fovObj is None): rad = network_obj.getRadarBy(rad_input['vals'][ir], rad_input['meth']) if not rad: continue site = rad.getSiteByDate(dateTime) if not site: continue # Set number of gates to be plotted egate = site.maxgate-1 if not maxGate else maxGate ebeam = site.maxbeam if not hasattr(mapObj, 'coords'): rad_fov = fov(site=site, ngates=egate+1, model=model, fov_dir=fov_dir) else: rad_fov = fov(site=site, ngates=egate+1, coords=mapObj.coords, model=model, date_time=dateTime, fov_dir=fov_dir) else: rad_fov = fovObj egate = len(fovObj.gates) ebeam = len(fovObj.beams) if rangeLimits is not None: sgate = rangeLimits[0] egate = rangeLimits[1] else: sgate = 0 if beamLimits is not None: sbeam = beamLimits[0] ebeam = beamLimits[1] else: sbeam = 0 if model == 'GS': # Ground scatter model is not defined for close in rangegates. # np.nan will be returned for these gates. # Set sGate >= to the first rangegate that has real values. not_finite = np.logical_not(np.isfinite(rad_fov.lonFull)) grid = np.tile(np.arange(rad_fov.lonFull.shape[1]), (rad_fov.lonFull.shape[0],1)) grid[not_finite] = 999999 tmp_sGate = (np.min(grid,axis=1)).max() if tmp_sGate > sgate: sgate = tmp_sGate # Get radar coordinates in map projection if hasattr(mapObj, 'coords'): x, y = mapObj(rad_fov.lonFull, rad_fov.latFull, coords=rad_fov.coords) else: x, y = mapObj(rad_fov.lonFull, rad_fov.latFull) # Plot field of view # Create contour contour_x = concatenate((x[sbeam,sgate:egate], x[sbeam:ebeam,egate], x[ebeam,egate:sgate:-1], x[ebeam:sbeam:-1,sgate])) contour_y = concatenate((y[sbeam,sgate:egate], y[sbeam:ebeam,egate], y[ebeam,egate:sgate:-1], y[ebeam:sbeam:-1,sgate])) # Set the color if a different color has been specified for each radar if isinstance(lineColor, list) and len(lineColor) > ir: lcolor=lineColor[ir] # Plot contour mapObj.plot(contour_x, contour_y, color=lcolor, zorder=zorder, linewidth=lineWidth) # Field of view fill if fovColor: contour = transpose(vstack((contour_x,contour_y))) patch = Polygon(contour, color=fovColor, alpha=fovAlpha, zorder=zorder) mapObj.ax.add_patch(patch) # Beams fill if beams: try: [b for b in beams] except: beams = [beams] for ib in beams: if not (0 <= ib <= x.shape[0]): continue if not beamsColors: bcol_rgb = ib/float(x.shape[0]) bcol = (bcol_rgb/2., bcol_rgb, 1) else: bcol = beamsColors[beams.index(ib)] contour_x = concatenate((x[ib,sgate:egate+1], x[ib:ib+2,egate], x[ib+1,egate:sgate:-1], x[ib+1:ib-1:-1,sgate])) contour_y = concatenate((y[ib,sgate:egate+1], y[ib:ib+2,egate], y[ib+1,egate:sgate:-1], y[ib+1:ib-1:-1,sgate])) contour = transpose(vstack((contour_x, contour_y))) patch = Polygon(contour, color=bcol, alpha=.4, zorder=zorder) mapObj.ax.add_patch(patch) return
def plotRti(myBeamList,rad,bmnum=7, params=['velocity','power','width'],\ scales=[], channel='a',coords='gate',colors='lasse',yrng=-1,\ gsct=False,lowGray=False, filtered=False,tFreqBands=[],\ figure=None,xtick_size=9,ytick_size=9,myFov = None,\ xticks=None,axvlines=None,rTime = None,title=None): """create an rti plot for a secified radar and time period **Args**: * **myBeamList** List of beam information * **rad** (str): the 3 letter radar code, e.g. 'bks' * **[bmnum] (int)**: The beam to plot. default: 7 * **[params]** (list): a list of the fit parameters to plot, allowable values are: ['velocity', 'power', 'width', 'elevation', 'phi0']. default: ['velocity', 'power', 'width'] * **[scales]** (list): a list of the min/max values for the color scale for each param. If omitted, default scales will be used. If present, the list should be n x 2 where n is the number of elements in the params list. Use an empty list for default range, e.g. [[-250,300],[],[]]. default: [[-200,200],[0,30],[0,150]] * **[channel]** (char): the channel you wish to plot, e.g. 'a', 'b', 'c', ... default: 'a' * **[coords]** (str): the coordinates to use for the y axis. The allowable values are 'gate', 'rng', 'geo', 'mag' default: 'gate' * **[colors]** (str): a string indicating what color bar to use, valid inputs are ['lasse','aj']. default: 'lasse' * **[yrng]** (list or -1): a list indicating the min and max values for the y axis in the chosen coordinate system, or a -1 indicating to plot everything. default: -1. * **[gsct]** (boolean): a flag indicating whether to plot ground scatter as gray. default: False (ground scatter plotted normally) * **[lowGray]** (boolean): a flag indicating whether to plot low velocity scatter as gray. default: False (low velocity scatter plotted normally) * **[filtered]** (boolean): a flag indicating whether to boxcar filter the data. default = False (no filter) * **[tFreqBands]** (list): a list of the min/max values for the transmitter frequencies in kHz. If omitted, the default band will be used. If more than one band is specified, retfig will cause only the last one to be returned. default: [[8000,20000]] * **[figure]** (matplotlib.figure) figure object to plot on. If None, a figure object will be created for you. * **[xtick_size]**: (int) fontsize of xtick labels * **[ytick_size]**: (int) fontsize of ytick labels * **[myFov]**: field of view parameters * **[xticks]**: (list) datetime.datetime objects indicating the location of xticks * **[axvlines]**: (list) datetime.datetime objects indicating the location vertical lines marking the plot * **[rTime]**: (datetime) current datetime to go on the title of the graph * **[title]**: (str) title string for figure **Returns**: * Return figure **Example**: :: import datetime as dt import matplotlib.pyplot as plot plotRti(myBeamList,'ade',params=['velocity','power','width'], scales=[[-1000,1000],[0,30],[0,500]],gsct=True, bmnum = 8,figure = plot.figure(),rTime = timeNow, title = 'Adak East',myFov = fovs) Written by AJ 20121002 Modified by Matt W. 20130715 Modified by Nathaniel F. 20131031 (added plotTerminator) Modified by Michelle S. 20160324 (updated for real time data plotting) """ #check the inputs assert (isinstance(rad, str) and len(rad) == 3), 'error, rad must be a string 3 chars long' assert(coords == 'gate' or coords == 'rng' or coords == 'geo' or coords == 'mag'),\ "error, coords must be one of 'gate','rng','geo','mag" assert (isinstance(bmnum, int)), 'error, beam must be integer' assert (0 < len(params) < 6), 'error, must input between 1 and 5 params in LIST form' for i in range(0, len(params)): assert(params[i] == 'velocity' or params[i] == 'power' or params[i] == 'width' or \ params[i] == 'elevation' or params[i] == 'phi0'), \ "error, allowable params are 'velocity','power','width','elevation','phi0'" assert(scales == [] or len(scales)==len(params)), \ 'error, if present, scales must have same number of elements as params' assert(yrng == -1 or (isinstance(yrng,list) and yrng[0] <= yrng[1])), \ 'error, yrng must equal -1 or be a list with the 2nd element larger than the first' assert (colors == 'lasse' or colors == 'aj'), "error, valid inputs for color are 'lasse' and 'aj'" #assign any default color scales tscales = [] for i in range(0, len(params)): if (scales == [] or scales[i] == []): if (params[i] == 'velocity'): tscales.append([-200, 200]) elif (params[i] == 'power'): tscales.append([0, 30]) elif (params[i] == 'width'): tscales.append([0, 150]) elif (params[i] == 'elevation'): tscales.append([0, 50]) elif (params[i] == 'phi0'): tscales.append([-numpy.pi, numpy.pi]) else: tscales.append(scales[i]) scales = tscales #assign default frequency band tbands = [] if tFreqBands == []: tbands.append([8000, 20000]) else: for band in tFreqBands: #make sure that starting frequncy is less than the ending frequency for each band assert (band[0] < band[1] ), "Starting frequency must be less than ending frequency!" tbands.append(band) if not myBeamList: logging.debug( 'error, no data available for the requested time/radar/filetype combination' ) return None #initialize empty lists vel,pow,wid,elev,phi0,times,freq,cpid,nave,nsky,nsch,slist,mode,rsep,nrang,frang,gsflg = \ [],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[] for i in range(len(tbands)): times.append([]) cpid.append([]) nave.append([]) nsky.append([]) rsep.append([]) nrang.append([]) frang.append([]) nsch.append([]) freq.append([]) slist.append([]) mode.append([]) vel.append([]) pow.append([]) wid.append([]) elev.append([]) phi0.append([]) gsflg.append([]) timeThen = datetime.datetime.utcnow() - datetime.timedelta(days=1) #read the parameters of interest for myBeam in myBeamList: if myBeam.time > timeThen: ids = myBeam.stid times[i].append(myBeam.time) cpid[i].append(myBeam.cp) nave[i].append(myBeam.prm.nave) nsky[i].append(myBeam.prm.noisesky) rsep[i].append(myBeam.prm.rsep) nrang[i].append(myBeam.prm.nrang) frang[i].append(myBeam.prm.frang) nsch[i].append(myBeam.prm.noisesearch) freq[i].append(myBeam.prm.tfreq / 1e3) slist[i].append(myBeam.fit.slist) mode[i].append(myBeam.prm.ifmode) if ('velocity' in params): vel[i].append(myBeam.fit.v) if ('power' in params): pow[i].append(myBeam.fit.p_l) if ('width' in params): wid[i].append(myBeam.fit.w_l) if ('elevation' in params): elev[i].append(myBeam.fit.elv) if ('phi0' in params): phi0[i].append(myBeam.fit.phi0) gsflg[i].append(myBeam.fit.gflg) for fplot in range(len(tbands)): #get/create a figure rtiFig = figure #give the plot a title rtiTitle(rtiFig, rTime, title, rad, bmnum) #plot the noise bar plotNoise(rtiFig, times[fplot], nsky[fplot], nsch[fplot]) #plot the frequency bar plotFreq(rtiFig, times[fplot], freq[fplot], nave[fplot]) #plot the cpid bar plotCpid(rtiFig, times[fplot], cpid[fplot], mode[fplot]) #plot each of the parameter panels figtop = .77 figheight = .72 / len(params) for p in range(len(params)): if (params[p] == 'velocity'): pArr = vel[fplot] elif (params[p] == 'power'): pArr = pow[fplot] elif (params[p] == 'width'): pArr = wid[fplot] elif (params[p] == 'elevation'): pArr = elev[fplot] elif (params[p] == 'phi0'): pArr = phi0[fplot] time.sleep(0.1) pos = [ .1, figtop - figheight * (p + 1) + .02, .76, figheight - .02 ] #draw the axis ax = drawAxes(rtiFig,times[fplot],rad,cpid[fplot],bmnum,nrang[fplot],frang[fplot],rsep[fplot],ids,p==len(params)-1,yrng=yrng,coords=coords,\ pos=pos,xtick_size=xtick_size,ytick_size=ytick_size,xticks=xticks,axvlines=axvlines, myFov=myFov) if (pArr == []): continue rmax = max(nrang[fplot]) data = numpy.zeros((len(times[fplot]) * 2, rmax)) - 150000 if gsct: gsdata = numpy.empty((len(times[fplot]) * 2, rmax)) x = numpy.empty(len(times[fplot]) * 2) tcnt = 0 dt_list = [] for i in range(len(times[fplot])): x[tcnt] = date2num(times[fplot][i]) dt_list.append(times[fplot][i]) if (i < len(times[fplot]) - 1): if (date2num(times[fplot][i + 1]) - x[tcnt] > 4. / 1440.): tcnt += 1 x[tcnt] = x[tcnt - 1] + 1. / 1440. dt_list.append(num2date(x[tcnt])) tcnt += 1 if (pArr[i] == []): continue if slist[fplot][i] != None: for j in range(len(slist[fplot][i])): if (not gsct or gsflg[fplot][i][j] == 0) or params[p] == 'power': data[tcnt][int(slist[fplot][i][j])] = pArr[i][j] elif gsct and gsflg[fplot][i][j] == 1: data[tcnt][int(slist[fplot][i][j])] = -100000. tmpdata = numpy.ma.masked_where(data <= -150000, data) if (coords != 'gate' and coords != 'rng'): if myFov is None: site = RadarPos(ids) myFov = radFov.fov(site=site, ngates=rmax, nbeams=site.maxbeam, rsep=rsep[fplot][0], coords=coords) myLat = myFov.latCenter[bmnum] myLon = myFov.lonCenter[bmnum] if (coords == 'gate'): y = numpy.linspace(0, rmax, rmax + 1) elif (coords == 'rng'): y = numpy.linspace(frang[fplot][0], rmax * rsep[fplot][0], rmax + 1) else: y = myFov.latFull[bmnum] X, Y = numpy.meshgrid(x[:tcnt], y) cmap, norm, bounds = plotUtils.genCmap(params[p], scales[p], colors=colors, lowGray=lowGray) cmap.set_bad('w', 1.0) pcoll = ax.pcolormesh(X, Y, tmpdata[:tcnt][:].T, lw=0.01, edgecolors='None', alpha=1, cmap=cmap, norm=norm) try: cb = plotUtils.drawCB( rtiFig, pcoll, cmap, norm, map=0, pos=[pos[0] + pos[2] + .02, pos[1], 0.02, pos[3]]) except: cb = rtiFig.colorbar(pcoll, orientation='vertical', shrink=.65, fraction=.1) l = [] #define the colorbar labels for i in range(0, len(bounds)): l.append(str(int(bounds[i]))) cb.ax.set_yticklabels(l) #set colorbar ticklabel size for t in cb.ax.get_yticklabels(): t.set_fontsize(9) #set colorbar label if (params[p] == 'velocity'): cb.set_label('Velocity [m/s]', size=10) if (params[p] == 'grid'): cb.set_label('Velocity [m/s]', size=10) if (params[p] == 'power'): cb.set_label('Power [dB]', size=10) if (params[p] == 'width'): cb.set_label('Spec Wid [m/s]', size=10) if (params[p] == 'elevation'): cb.set_label('Elev [deg]', size=10) if (params[p] == 'phi0'): cb.set_label('Phi0 [rad]', size=10) #end of plotting for loop return rtiFig
def drawAxes(myFig,times,rad,cpid,bmnum,nrang,frang,rsep,bottom,ids,yrng=-1,\ coords='gate',pos=[.1,.05,.76,.72],xtick_size=9,\ ytick_size=9,xticks=None,axvlines=None, myFov = None): """draws empty axes for an rti plot **Args**: * **myFig**: the MPL figure we are plotting to * **times**: a list of datetime objects referencing the beam soundings * **rad**: 3 letter radar code * **cpid**: list of the cpids or the beam soundings * **bmnum**: beam number being plotted * **nrang**: list of nrang for the beam soundings * **frang**: list of frang of the beam soundings * **rsep**: list of rsep of the beam soundings * **bottom**: flag indicating if we are at the bottom of the page * **[yrng]**: range of y axis, -1=autoscale (default) * **[coords]**: y axis coordinate system, acceptable values are 'geo', 'mag', 'gate', 'rng' * **[pos]**: position of the plot * **[xtick_size]**: fontsize of xtick labels * **[ytick_size]**: fontsize of ytick labels * **[xticks]**: (list) datetime.datetime objects indicating the location of xticks * **[axvlines]**: (list) datetime.datetime objects indicating the location vertical lines marking the plot **Returns**: * **ax**: an axes object **Example: :: ax = drawAxes(aFig,times,rad,cpid,beam,nrang,frang,rsep,0) Written by AJ 20121002 """ nrecs = len(times) #add an axes to the figure ax = myFig.add_axes(pos) ax.yaxis.set_tick_params(direction='out') ax.xaxis.set_tick_params(direction='out') ax.yaxis.set_tick_params(direction='out', which='minor') ax.xaxis.set_tick_params(direction='out', which='minor') #draw the axes ax.plot_date(date2num(times), numpy.arange(len(times)), fmt='w', \ tz=None, xdate=True, ydate=False, alpha=0.0) if (yrng == -1): ymin, ymax = 99999999, -999999999 if (coords != 'gate'): oldCpid = -99999999 for i in range(len(cpid)): if (cpid[i] == oldCpid): continue oldCpid = cpid[i] if (coords == 'geo' or coords == 'mag'): if myFov is None: site = RadarPos(ids) myFov = radFov.fov(site=site, ngates=nrang[i], nbeams=site.maxbeam, rsep=rsep[i], coords=coords) else: ymin = 0 if (nrang[i] * rsep[i] + frang[i] > ymax): ymax = nrang[i] * rsep[i] + frang[i] else: ymin, ymax = 0, max(nrang) else: ymin, ymax = yrng[0], yrng[1] xmin, xmax = date2num(times[0]), date2num(times[len(times) - 1]) xrng = (xmax - xmin) inter = int(round(xrng / 6. * 86400.)) inter2 = int(round(xrng / 24. * 86400.)) #format the x axis ax.xaxis.set_minor_locator(SecondLocator(interval=inter2)) ax.xaxis.set_major_locator(SecondLocator(interval=inter)) if (not bottom): for tick in ax.xaxis.get_major_ticks(): tick.label.set_fontsize(0) else: if xticks is not None: ax.xaxis.set_ticks(xticks) if axvlines is not None: for line in axvlines: ax.axvline(line, color='k', ls='--') for tick in ax.xaxis.get_major_ticks(): tick.label.set_fontsize(xtick_size) ax.xaxis.set_major_formatter(DateFormatter('%H:%M:%S')) ax.xaxis.set_label_text('UT') #set ytick size for tick in ax.yaxis.get_major_ticks(): tick.label.set_fontsize(ytick_size) #format y axis depending on coords if (coords == 'gate'): ax.yaxis.set_label_text('Range gate', size=10) ax.yaxis.set_major_formatter(FormatStrFormatter('%d')) ax.yaxis.set_major_locator(MultipleLocator((ymax - ymin) / 5.)) ax.yaxis.set_minor_locator(MultipleLocator((ymax - ymin) / 25.)) elif (coords == 'geo' or coords == 'mag'): if (coords == 'mag'): ax.yaxis.set_label_text('Mag Lat [deg]', size=10) else: ax.yaxis.set_label_text('Geo Lat [deg]', size=10) ax.yaxis.set_major_formatter(FormatStrFormatter('%0.2f')) ax.yaxis.set_major_locator(MultipleLocator((ymax - ymin) / 5.)) ax.yaxis.set_minor_locator(MultipleLocator((ymax - ymin) / 25.)) elif (coords == 'rng'): ax.yaxis.set_label_text('Slant Range [km]', size=10) ax.yaxis.set_major_formatter(FormatStrFormatter('%d')) ax.yaxis.set_major_locator(MultipleLocator(1000)) ax.yaxis.set_minor_locator(MultipleLocator(250)) ax.set_xlim(left=xmin, right=xmax) ax.set_ylim(bottom=ymin, top=ymax) return ax
def plotRti(myBeamList,rad,bmnum=7, params=['velocity','power','width'],\ scales=[], channel='a',coords='gate',colors='lasse',yrng=-1,\ gsct=False,lowGray=False, filtered=False,tFreqBands=[],\ figure=None,xtick_size=9,ytick_size=9,myFov = None,\ xticks=None,axvlines=None,rTime = None,title=None): """create an rti plot for a secified radar and time period **Args**: * **myBeamList** List of beam information * **rad** (str): the 3 letter radar code, e.g. 'bks' * **[bmnum] (int)**: The beam to plot. default: 7 * **[params]** (list): a list of the fit parameters to plot, allowable values are: ['velocity', 'power', 'width', 'elevation', 'phi0']. default: ['velocity', 'power', 'width'] * **[scales]** (list): a list of the min/max values for the color scale for each param. If omitted, default scales will be used. If present, the list should be n x 2 where n is the number of elements in the params list. Use an empty list for default range, e.g. [[-250,300],[],[]]. default: [[-200,200],[0,30],[0,150]] * **[channel]** (char): the channel you wish to plot, e.g. 'a', 'b', 'c', ... default: 'a' * **[coords]** (str): the coordinates to use for the y axis. The allowable values are 'gate', 'rng', 'geo', 'mag' default: 'gate' * **[colors]** (str): a string indicating what color bar to use, valid inputs are ['lasse','aj']. default: 'lasse' * **[yrng]** (list or -1): a list indicating the min and max values for the y axis in the chosen coordinate system, or a -1 indicating to plot everything. default: -1. * **[gsct]** (boolean): a flag indicating whether to plot ground scatter as gray. default: False (ground scatter plotted normally) * **[lowGray]** (boolean): a flag indicating whether to plot low velocity scatter as gray. default: False (low velocity scatter plotted normally) * **[filtered]** (boolean): a flag indicating whether to boxcar filter the data. default = False (no filter) * **[tFreqBands]** (list): a list of the min/max values for the transmitter frequencies in kHz. If omitted, the default band will be used. If more than one band is specified, retfig will cause only the last one to be returned. default: [[8000,20000]] * **[figure]** (matplotlib.figure) figure object to plot on. If None, a figure object will be created for you. * **[xtick_size]**: (int) fontsize of xtick labels * **[ytick_size]**: (int) fontsize of ytick labels * **[myFov]**: field of view parameters * **[xticks]**: (list) datetime.datetime objects indicating the location of xticks * **[axvlines]**: (list) datetime.datetime objects indicating the location vertical lines marking the plot * **[rTime]**: (datetime) current datetime to go on the title of the graph * **[title]**: (str) title string for figure **Returns**: * Return figure **Example**: :: import datetime as dt import matplotlib.pyplot as plot plotRti(myBeamList,'ade',params=['velocity','power','width'], scales=[[-1000,1000],[0,30],[0,500]],gsct=True, bmnum = 8,figure = plot.figure(),rTime = timeNow, title = 'Adak East',myFov = fovs) Written by AJ 20121002 Modified by Matt W. 20130715 Modified by Nathaniel F. 20131031 (added plotTerminator) Modified by Michelle S. 20160324 (updated for real time data plotting) """ #check the inputs assert(isinstance(rad,str) and len(rad) == 3),'error, rad must be a string 3 chars long' assert(coords == 'gate' or coords == 'rng' or coords == 'geo' or coords == 'mag'),\ "error, coords must be one of 'gate','rng','geo','mag" assert(isinstance(bmnum,int)),'error, beam must be integer' assert(0 < len(params) < 6),'error, must input between 1 and 5 params in LIST form' for i in range(0,len(params)): assert(params[i] == 'velocity' or params[i] == 'power' or params[i] == 'width' or \ params[i] == 'elevation' or params[i] == 'phi0'), \ "error, allowable params are 'velocity','power','width','elevation','phi0'" assert(scales == [] or len(scales)==len(params)), \ 'error, if present, scales must have same number of elements as params' assert(yrng == -1 or (isinstance(yrng,list) and yrng[0] <= yrng[1])), \ 'error, yrng must equal -1 or be a list with the 2nd element larger than the first' assert(colors == 'lasse' or colors == 'aj'),"error, valid inputs for color are 'lasse' and 'aj'" #assign any default color scales tscales = [] for i in range(0,len(params)): if(scales == [] or scales[i] == []): if(params[i] == 'velocity'): tscales.append([-200,200]) elif(params[i] == 'power'): tscales.append([0,30]) elif(params[i] == 'width'): tscales.append([0,150]) elif(params[i] == 'elevation'): tscales.append([0,50]) elif(params[i] == 'phi0'): tscales.append([-numpy.pi,numpy.pi]) else: tscales.append(scales[i]) scales = tscales #assign default frequency band tbands = [] if tFreqBands == []: tbands.append([8000,20000]) else: for band in tFreqBands: #make sure that starting frequncy is less than the ending frequency for each band assert(band[0] < band[1]),"Starting frequency must be less than ending frequency!" tbands.append(band) if not myBeamList: logging.debug('error, no data available for the requested time/radar/filetype combination') return None #initialize empty lists vel,pow,wid,elev,phi0,times,freq,cpid,nave,nsky,nsch,slist,mode,rsep,nrang,frang,gsflg = \ [],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[] for i in range(len(tbands)): times.append([]) cpid.append([]) nave.append([]) nsky.append([]) rsep.append([]) nrang.append([]) frang.append([]) nsch.append([]) freq.append([]) slist.append([]) mode.append([]) vel.append([]) pow.append([]) wid.append([]) elev.append([]) phi0.append([]) gsflg.append([]) timeThen = datetime.datetime.utcnow() - datetime.timedelta(days=1) #read the parameters of interest for myBeam in myBeamList: if myBeam.time > timeThen: ids = myBeam.stid times[i].append(myBeam.time) cpid[i].append(myBeam.cp) nave[i].append(myBeam.prm.nave) nsky[i].append(myBeam.prm.noisesky) rsep[i].append(myBeam.prm.rsep) nrang[i].append(myBeam.prm.nrang) frang[i].append(myBeam.prm.frang) nsch[i].append(myBeam.prm.noisesearch) freq[i].append(myBeam.prm.tfreq/1e3) slist[i].append(myBeam.fit.slist) mode[i].append(myBeam.prm.ifmode) if('velocity' in params): vel[i].append(myBeam.fit.v) if('power' in params): pow[i].append(myBeam.fit.p_l) if('width' in params): wid[i].append(myBeam.fit.w_l) if('elevation' in params): elev[i].append(myBeam.fit.elv) if('phi0' in params): phi0[i].append(myBeam.fit.phi0) gsflg[i].append(myBeam.fit.gflg) for fplot in range(len(tbands)): #get/create a figure rtiFig = figure #give the plot a title rtiTitle(rtiFig,rTime,title,rad,bmnum) #plot the noise bar plotNoise(rtiFig,times[fplot],nsky[fplot],nsch[fplot]) #plot the frequency bar plotFreq(rtiFig,times[fplot],freq[fplot],nave[fplot]) #plot the cpid bar plotCpid(rtiFig,times[fplot],cpid[fplot],mode[fplot]) #plot each of the parameter panels figtop = .77 figheight = .72/len(params) for p in range(len(params)): if(params[p] == 'velocity'): pArr = vel[fplot] elif(params[p] == 'power'): pArr = pow[fplot] elif(params[p] == 'width'): pArr = wid[fplot] elif(params[p] == 'elevation'): pArr = elev[fplot] elif(params[p] == 'phi0'): pArr = phi0[fplot] time.sleep(0.1) pos = [.1,figtop-figheight*(p+1)+.02,.76,figheight-.02] #draw the axis ax = drawAxes(rtiFig,times[fplot],rad,cpid[fplot],bmnum,nrang[fplot],frang[fplot],rsep[fplot],ids,p==len(params)-1,yrng=yrng,coords=coords,\ pos=pos,xtick_size=xtick_size,ytick_size=ytick_size,xticks=xticks,axvlines=axvlines, myFov=myFov) if(pArr == []): continue rmax = max(nrang[fplot]) data=numpy.zeros((len(times[fplot])*2,rmax))-150000 if gsct: gsdata=numpy.empty((len(times[fplot])*2,rmax)) x=numpy.empty(len(times[fplot])*2) tcnt = 0 dt_list = [] for i in range(len(times[fplot])): x[tcnt]=date2num(times[fplot][i]) dt_list.append(times[fplot][i]) if(i < len(times[fplot])-1): if(date2num(times[fplot][i+1])-x[tcnt] > 4./1440.): tcnt += 1 x[tcnt] = x[tcnt-1]+1./1440. dt_list.append(num2date(x[tcnt])) tcnt += 1 if(pArr[i] == []): continue if slist[fplot][i] != None : for j in range(len(slist[fplot][i])): if (not gsct or gsflg[fplot][i][j] == 0) or params[p] == 'power': data[tcnt][int(slist[fplot][i][j])] = pArr[i][j] elif gsct and gsflg[fplot][i][j] == 1: data[tcnt][int(slist[fplot][i][j])] = -100000. tmpdata = numpy.ma.masked_where(data <= -150000, data) if (coords != 'gate' and coords != 'rng'): if myFov is None: site = RadarPos(ids) myFov = radFov.fov(site=site,ngates=rmax,nbeams=site.maxbeam,rsep=rsep[fplot][0],coords=coords) myLat = myFov.latCenter[bmnum] myLon = myFov.lonCenter[bmnum] if(coords == 'gate'): y = numpy.linspace(0,rmax,rmax+1) elif(coords == 'rng'): y = numpy.linspace(frang[fplot][0],rmax*rsep[fplot][0],rmax+1) else: y = myFov.latFull[bmnum] X, Y = numpy.meshgrid(x[:tcnt], y) cmap,norm,bounds = plotUtils.genCmap(params[p],scales[p],colors=colors,lowGray=lowGray) cmap.set_bad('w',1.0) pcoll = ax.pcolormesh(X, Y, tmpdata[:tcnt][:].T, lw=0.01,edgecolors='None',alpha=1,cmap=cmap,norm=norm) try: cb = plotUtils.drawCB(rtiFig,pcoll,cmap,norm,map=0,pos=[pos[0]+pos[2]+.02, pos[1], 0.02, pos[3]]) except: cb = rtiFig.colorbar(pcoll,orientation='vertical',shrink=.65,fraction=.1) l = [] #define the colorbar labels for i in range(0,len(bounds)): l.append(str(int(bounds[i]))) cb.ax.set_yticklabels(l) #set colorbar ticklabel size for t in cb.ax.get_yticklabels(): t.set_fontsize(9) #set colorbar label if(params[p] == 'velocity'): cb.set_label('Velocity [m/s]',size=10) if(params[p] == 'grid'): cb.set_label('Velocity [m/s]',size=10) if(params[p] == 'power'): cb.set_label('Power [dB]',size=10) if(params[p] == 'width'): cb.set_label('Spec Wid [m/s]',size=10) if(params[p] == 'elevation'): cb.set_label('Elev [deg]',size=10) if(params[p] == 'phi0'): cb.set_label('Phi0 [rad]',size=10) #end of plotting for loop return rtiFig
def drawAxes(myFig,times,rad,cpid,bmnum,nrang,frang,rsep,bottom,ids,yrng=-1,\ coords='gate',pos=[.1,.05,.76,.72],xtick_size=9,\ ytick_size=9,xticks=None,axvlines=None, myFov = None): """draws empty axes for an rti plot **Args**: * **myFig**: the MPL figure we are plotting to * **times**: a list of datetime objects referencing the beam soundings * **rad**: 3 letter radar code * **cpid**: list of the cpids or the beam soundings * **bmnum**: beam number being plotted * **nrang**: list of nrang for the beam soundings * **frang**: list of frang of the beam soundings * **rsep**: list of rsep of the beam soundings * **bottom**: flag indicating if we are at the bottom of the page * **[yrng]**: range of y axis, -1=autoscale (default) * **[coords]**: y axis coordinate system, acceptable values are 'geo', 'mag', 'gate', 'rng' * **[pos]**: position of the plot * **[xtick_size]**: fontsize of xtick labels * **[ytick_size]**: fontsize of ytick labels * **[xticks]**: (list) datetime.datetime objects indicating the location of xticks * **[axvlines]**: (list) datetime.datetime objects indicating the location vertical lines marking the plot **Returns**: * **ax**: an axes object **Example: :: ax = drawAxes(aFig,times,rad,cpid,beam,nrang,frang,rsep,0) Written by AJ 20121002 """ nrecs = len(times) #add an axes to the figure ax = myFig.add_axes(pos) ax.yaxis.set_tick_params(direction='out') ax.xaxis.set_tick_params(direction='out') ax.yaxis.set_tick_params(direction='out',which='minor') ax.xaxis.set_tick_params(direction='out',which='minor') #draw the axes ax.plot_date(date2num(times), numpy.arange(len(times)), fmt='w', \ tz=None, xdate=True, ydate=False, alpha=0.0) if(yrng == -1): ymin,ymax = 99999999,-999999999 if(coords != 'gate'): oldCpid = -99999999 for i in range(len(cpid)): if(cpid[i] == oldCpid): continue oldCpid = cpid[i] if(coords == 'geo' or coords == 'mag'): if myFov is None: site = RadarPos(ids) myFov = radFov.fov(site=site, ngates=nrang[i],nbeams=site.maxbeam,rsep=rsep[i],coords=coords) else: ymin = 0 if(nrang[i]*rsep[i]+frang[i] > ymax): ymax = nrang[i]*rsep[i]+frang[i] else: ymin,ymax = 0,max(nrang) else: ymin,ymax = yrng[0],yrng[1] xmin,xmax = date2num(times[0]),date2num(times[len(times)-1]) xrng = (xmax-xmin) inter = int(round(xrng/6.*86400.)) inter2 = int(round(xrng/24.*86400.)) #format the x axis ax.xaxis.set_minor_locator(SecondLocator(interval=inter2)) ax.xaxis.set_major_locator(SecondLocator(interval=inter)) if(not bottom): for tick in ax.xaxis.get_major_ticks(): tick.label.set_fontsize(0) else: if xticks is not None: ax.xaxis.set_ticks(xticks) if axvlines is not None: for line in axvlines: ax.axvline(line,color='k',ls='--') for tick in ax.xaxis.get_major_ticks(): tick.label.set_fontsize(xtick_size) ax.xaxis.set_major_formatter(DateFormatter('%H:%M:%S')) ax.xaxis.set_label_text('UT') #set ytick size for tick in ax.yaxis.get_major_ticks(): tick.label.set_fontsize(ytick_size) #format y axis depending on coords if(coords == 'gate'): ax.yaxis.set_label_text('Range gate',size=10) ax.yaxis.set_major_formatter(FormatStrFormatter('%d')) ax.yaxis.set_major_locator(MultipleLocator((ymax-ymin)/5.)) ax.yaxis.set_minor_locator(MultipleLocator((ymax-ymin)/25.)) elif(coords == 'geo' or coords == 'mag'): if(coords == 'mag'): ax.yaxis.set_label_text('Mag Lat [deg]',size=10) else: ax.yaxis.set_label_text('Geo Lat [deg]',size=10) ax.yaxis.set_major_formatter(FormatStrFormatter('%0.2f')) ax.yaxis.set_major_locator(MultipleLocator((ymax-ymin)/5.)) ax.yaxis.set_minor_locator(MultipleLocator((ymax-ymin)/25.)) elif(coords == 'rng'): ax.yaxis.set_label_text('Slant Range [km]',size=10) ax.yaxis.set_major_formatter(FormatStrFormatter('%d')) ax.yaxis.set_major_locator(MultipleLocator(1000)) ax.yaxis.set_minor_locator(MultipleLocator(250)) ax.set_xlim(left=xmin,right=xmax) ax.set_ylim(bottom=ymin,top=ymax) return ax