def gen_retrieval_math(i, selection, t_all, t_mins, dxvec, drsq, center_ECEF,
                       stations_ECEF, dt_rms, min_stations=5,
                       max_z_guess=25.0e3):
    """ t_all is a N_stations x N_points masked array of arrival times at
        each station.
        t_min is an N-point array of the index of the first unmasked station 
        to receive a signal

        center_ECEF for the altitude check

        This streamlines the generator function, which emits a stream of 
        nonlinear least-squares solutions.
    """  
    m = t_mins[i]
    stations_ECEF2=stations_ECEF[selection]
    # Make a linear first guess
    p0 = linear_first_guess(np.array(t_all[:,i][selection]-t_all[m,i]),
                            dxvec[m][selection], 
                            drsq[m][selection])
    t_i =t_all[:,i][selection]-t_all[m,i]
    # Checking altitude in lat/lon/alt from local coordinates
    latlon = np.array(GeographicSystem().fromECEF(p0[0], p0[1],p0[2]))
    if (latlon[2]<0) | (latlon[2]>25000): 
        latlon[2] = 7000
        new = GeographicSystem().toECEF(latlon[0], latlon[1], latlon[2])
        p0[:3]=np.array(new)
    plsq = np.array([np.nan]*5)   
    plsq[:4], cov, infodict, mesg,ier = leastsq(residuals, p0, 
                            args=(t_i, stations_ECEF2), 
                            Dfun=dfunc,col_deriv=1,full_output=True) 
    plsq[4] = np.sum(infodict['fvec']*infodict['fvec'])/(
                     dt_rms*dt_rms*(float(np.shape(stations_ECEF2)[0]-4)))
    return plsq
Example #2
0
def dlonlat_at_grid_center(ctr_lat, ctr_lon, dx=4.0e3, dy=4.0e3,
    x_bnd = (-100e3, 100e3), y_bnd = (-100e3, 100e3),
    proj_datum = 'WGS84', proj_ellipse = 'WGS84'):
    """ 
    
    Utility function useful for producing a regular grid of lat/lon data, 
    where an approximate spacing (dx, dy) and total span of the grid (x_bnd, y_bnd) 
    is desired. Units are in meters.
    
    There is guaranteed to be distortion away from the grid center, i.e.,
    only the grid cells adjacent to the center location will have area dx * dy. 
    
    Likewise, the lat, lon range is calculated naively using dlat, dlon multiplied
    by the number of grid cells implied by x_bnd/dx, y_bnd/dy. This is the naive approach,
    but probably what's expected when specifying distances in kilometers for
    an inherently distorted lat/lon grid.
    
    Returns: 
    (dlon, dlat, lon_bnd, lat_bnd)
    corresponding to 
    (dx, dy, x_range, y_range)
    
    """

    # Use the Azimuthal equidistant projection as the method for converting to kilometers.
    proj_name = 'aeqd'
    
    mapProj = MapProjection(projection=proj_name, ctrLat=ctr_lat, ctrLon=ctr_lon, lat_ts=ctr_lat, 
                            lon_0=ctr_lon, lat_0=ctr_lat, lat_1=ctr_lat, ellipse=proj_ellipse, datum=proj_datum)
    geoProj = GeographicSystem()
    
    # Get dlat
    lon_n, lat_n, z_n = geoProj.fromECEF(*mapProj.toECEF(0,dy,0))
    dlat = lat_n - ctr_lat
    
    # Get dlon
    lon_e, lat_e, z_e = geoProj.fromECEF(*mapProj.toECEF(dx,0,0)) 
    dlon = lon_e - ctr_lon
    
    lon_min = ctr_lon + dlon * (x_bnd[0]/dx)
    lon_max = ctr_lon + dlon * (x_bnd[1]/dx)
    lat_min = ctr_lat + dlat * (y_bnd[0]/dy)
    lat_max = ctr_lat + dlat * (y_bnd[1]/dy)
    
    # Alternate method: lat lon for the actual distance to the NSEW in the projection
    #lon_range_n, lat_range_n, z_range_n = geoProj.fromECEF(*mapProj.toECEF(0,y_bnd,0))
    #lon_range_e, lat_range_e, z_range_e = geoProj.fromECEF(*mapProj.toECEF(x_bnd,0,0))
    
    return dlon, dlat, (lon_min, lon_max), (lat_min, lat_max)
Example #3
0
def grid_h5flashfiles(
    h5_filenames,
    start_time,
    end_time,
    frame_interval=120.0,
    dx=4.0e3,
    dy=4.0e3,
    x_bnd=(-100e3, 100e3),
    y_bnd=(-100e3, 100e3),
    z_bnd=(-20e3, 20e3),
    ctr_lat=35.23833,
    ctr_lon=-97.46028,
    min_points_per_flash=10,
    outpath="",
    flash_count_logfile=None,
    proj_name="aeqd",
    proj_datum="WGS84",
    proj_ellipse="WGS84",
    output_writer=write_cf_netcdf,
    output_filename_prefix="LMA",
    output_kwargs={},
    spatial_scale_factor=1.0 / 1000.0,
):
    from math import ceil

    """
    
    Create 2D plan-view density grids for events, flash origins, flash extents, and mean flash footprint
    
    frame_interval: Frame time-step in seconds
    dx, dy: horizontal grid size in m (or deg)
    {x,y,z}_bnd: horizontal grid edges in m
    ctr_lat, ctr_lon: coordinate center
    
    Uses an azimuthal equidistant map projection on the WGS84 ellipsoid.
    
    
    read_flashes
    
    filter_flash
    extract_events
    flash_to_frame
    
    frame0_broadcast, frame1_broadcast, ...
    
    each broadcaster above sends events and flashes to:
    projection( event_location), projection(flash_init_location), projection(event_location)
    which map respectively to:
    point_density->accum_on_grid(event density), point_density->accum_on_grid(flash init density), extent_density->accum_on_grid(flash_extent_density)

    grids are in an HDF5 file. how to handle flushing?
    """

    if flash_count_logfile is None:
        flash_count_logfile = sys.stdout

    # reference time is the date part of the start_time

    t_edges, duration = time_edges(start_time, end_time, frame_interval)
    t_ref, t_edges_seconds = seconds_since_start_of_day(start_time, t_edges)
    n_frames = len(t_edges) - 1

    xedge = np.arange(x_bnd[0], x_bnd[1] + dx, dx)
    yedge = np.arange(y_bnd[0], y_bnd[1] + dy, dy)

    x0 = xedge[0]
    y0 = yedge[0]

    if proj_name == "latlong":
        dx_units = "{0:6.4f}deg".format(dx)
        mapProj = GeographicSystem()
    else:
        dx_units = "{0:5.1f}m".format(dx)
        mapProj = MapProjection(
            projection=proj_name,
            ctrLat=ctr_lat,
            ctrLon=ctr_lon,
            lat_ts=ctr_lat,
            lon_0=ctr_lon,
            lat_0=ctr_lat,
            lat_1=ctr_lat,
            ellipse=proj_ellipse,
            datum=proj_datum,
        )
    geoProj = GeographicSystem()

    event_density_grid = np.zeros((xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype="int32")
    init_density_grid = np.zeros((xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype="int32")
    extent_density_grid = np.zeros((xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype="int32")
    footprint_grid = np.zeros((xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype="float32")

    all_frames = []
    extent_frames = []
    init_frames = []
    event_frames = []
    for i in range(n_frames):
        extent_out = {"name": "extent"}
        init_out = {"name": "init"}
        event_out = {"name": "event"}
        accum_event_density = density_to_files.accumulate_points_on_grid(
            event_density_grid[:, :, i], xedge, yedge, out=event_out, label="event"
        )
        accum_init_density = density_to_files.accumulate_points_on_grid(
            init_density_grid[:, :, i], xedge, yedge, out=init_out, label="init"
        )
        accum_extent_density = density_to_files.accumulate_points_on_grid(
            extent_density_grid[:, :, i], xedge, yedge, out=extent_out, label="extent"
        )
        accum_footprint = density_to_files.accumulate_points_on_grid(
            footprint_grid[:, :, i], xedge, yedge, label="footprint"
        )
        extent_out["func"] = accum_extent_density
        init_out["func"] = accum_init_density
        event_out["func"] = accum_event_density
        extent_frames.append(extent_out)
        init_frames.append(init_out)
        event_frames.append(event_out)

        event_density_target = density_to_files.point_density(accum_event_density)
        init_density_target = density_to_files.point_density(accum_init_density)
        extent_density_target = density_to_files.extent_density(x0, y0, dx, dy, accum_extent_density)
        mean_footprint_target = density_to_files.extent_density(x0, y0, dx, dy, accum_footprint, weight_key="area")

        spew_to_density_types = density_to_files.broadcast(
            (
                density_to_files.project(
                    "lon", "lat", "alt", mapProj, geoProj, event_density_target, use_flashes=False
                ),
                density_to_files.project(
                    "init_lon", "init_lat", "init_alt", mapProj, geoProj, init_density_target, use_flashes=True
                ),
                density_to_files.project(
                    "lon", "lat", "alt", mapProj, geoProj, extent_density_target, use_flashes=False
                ),
                density_to_files.project(
                    "lon", "lat", "alt", mapProj, geoProj, mean_footprint_target, use_flashes=False
                ),
            )
        )

        all_frames.append(density_to_files.extract_events_for_flashes(spew_to_density_types))

    frame_count_log = density_to_files.flash_count_log(flash_count_logfile)

    framer = density_to_files.flashes_to_frames(
        t_edges_seconds, all_frames, time_key="start", time_edges_datetime=t_edges, flash_counter=frame_count_log
    )

    read_flashes(h5_filenames, framer, base_date=t_ref, min_points=min_points_per_flash)

    # print 'event_density_grid ', id(event_density_grid[:,:,-1])
    # print 'extent_density_grid', id(extent_density_grid[:,:,-1])
    # print 'init_density_grid  ', id(init_density_grid[:,:,-1])

    x_coord = (xedge[:-1] + xedge[1:]) / 2.0
    y_coord = (yedge[:-1] + yedge[1:]) / 2.0
    nx = x_coord.shape[0]
    ny = y_coord.shape[0]

    x_all, y_all = (a.T for a in np.meshgrid(x_coord, y_coord))
    assert x_all.shape == y_all.shape
    assert x_all.shape[0] == nx
    assert x_all.shape[1] == ny
    z_all = np.zeros_like(x_all)

    lons, lats, alts = x, y, z = geoProj.fromECEF(*mapProj.toECEF(x_all, y_all, z_all))
    lons.shape = x_all.shape
    lats.shape = y_all.shape

    outflile_basename = os.path.join(
        outpath,
        "%s_%s_%d_%dsrc_%s-dx_"
        % (
            output_filename_prefix,
            start_time.strftime("%Y%m%d_%H%M%S"),
            to_seconds(duration),
            min_points_per_flash,
            dx_units,
        ),
    )

    outfiles = (
        outflile_basename + "flash_extent.nc",
        outflile_basename + "flash_init.nc",
        outflile_basename + "source.nc",
        outflile_basename + "footprint.nc",
    )

    outgrids = (extent_density_grid, init_density_grid, event_density_grid, footprint_grid)

    field_names = ("flash_extent", "flash_initiation", "lma_source", "flash_footprint")

    field_descriptions = (
        "LMA flash extent density",
        "LMA flash initiation density",
        "LMA source density",
        "LMA local mean flash area",
    )

    if proj_name == "latlong":
        density_units = "grid"
    else:
        density_units = "{0:5.1f} km^2".format(dx / 1000.0 * dy / 1000.0).lstrip()
    time_units = "{0:5.1f} min".format(frame_interval / 60.0).lstrip()
    density_label = "Count per " + density_units + " pixel per " + time_units

    field_units = (density_label, density_label, density_label, "km^2 per flash")

    output_writer(
        outfiles[0],
        t_ref,
        np.asarray(t_edges_seconds[:-1]),
        x_coord * spatial_scale_factor,
        y_coord * spatial_scale_factor,
        lons,
        lats,
        ctr_lat,
        ctr_lon,
        outgrids[0],
        field_names[0],
        field_descriptions[0],
        grid_units=field_units[0],
        **output_kwargs
    )
    output_writer(
        outfiles[1],
        t_ref,
        np.asarray(t_edges_seconds[:-1]),
        x_coord * spatial_scale_factor,
        y_coord * spatial_scale_factor,
        lons,
        lats,
        ctr_lat,
        ctr_lon,
        outgrids[1],
        field_names[1],
        field_descriptions[1],
        grid_units=field_units[1],
        **output_kwargs
    )
    output_writer(
        outfiles[2],
        t_ref,
        np.asarray(t_edges_seconds[:-1]),
        x_coord * spatial_scale_factor,
        y_coord * spatial_scale_factor,
        lons,
        lats,
        ctr_lat,
        ctr_lon,
        outgrids[2],
        field_names[2],
        field_descriptions[2],
        grid_units=field_units[2],
        **output_kwargs
    )
    output_writer(
        outfiles[3],
        t_ref,
        np.asarray(t_edges_seconds[:-1]),
        x_coord * spatial_scale_factor,
        y_coord * spatial_scale_factor,
        lons,
        lats,
        ctr_lat,
        ctr_lon,
        outgrids[3],
        field_names[3],
        field_descriptions[3],
        format="f",
        grid_units=field_units[3],
        **output_kwargs
    )

    print "max extent is", extent_density_grid.max()

    return x_coord, y_coord, lons, lats, extent_density_grid, outfiles, field_names
Example #4
0
import matplotlib.pyplot as plt
import datetime
import yt
import pyart
import os

from yt.visualization.api import Streamlines
from yt.visualization.volume_rendering.api import Scene, VolumeSource, LineSource, PointSource
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.image as mpimg

import readfunctions as rf
import lmasources as ls
from coordinateSystems import GeographicSystem, MapProjection

geo = GeographicSystem()

for filename in os.listdir('/localdata/wind_analysis/'):
    if filename[-8:] == '_var.out':
        print(filename)

        dataf = rf.outfile('/localdata/wind_analysis/' + filename)
        r, u, v, w = dataf.read_data()  # These are in z,y,x
        lon, lat, alt = dataf.latlon(geo)

        rx, ry, rz = dataf.data_grid()
        rx = rx.reshape(np.shape(w))
        ry = ry.reshape(np.shape(w))
        rz = rz.reshape(np.shape(w))

        lma_directory = '/home/vanna.chmielewski/analyzedlightning/notgz/'
def quick_method(aves,
                 sq,
                 fde,
                 xint=5000,
                 altitude=7000,
                 station_requirement=6,
                 c0=3.0e8,
                 mindist=300000):
    """ This function derives the minimum detectable source power and 
        corresponding source and flash detection efficiencies at points within
        300 km of the network with grid spacing xint at altitude m MSL

        aves is a (N-stations,(lat,lon,alt,threshold in dBm) array of station
        locations)

        sq is the quantile of the source powers in the power distribution

        fde is the quantile array of expected points per flash

        stations_requirement is the minimum number of stations to retreive a
        signal in order to find a solution
        
        c0 is th speed of light

        mindist is used to find the min/max x- and y- grid coordinates from 
        the min/max station locations. Ex: A value of 300000 (m) is at least 
        600 by 600 km in x and y.

        Also performs check of line of sight based on Earth curvature

        Returns: latitude of grid points, longitude of grid points, source
        detection efficiency (%), flash detection efficiency (%), minimum 
        detectable source power (dBW)       
    """
    center = (np.mean(aves[:, 0]), np.mean(aves[:, 1]), np.mean(aves[:, 2]))
    geo = GeographicSystem()
    mapp = MapProjection
    projl = MapProjection(projection='laea', lat_0=center[0], lon_0=center[1])

    lat, lon, alt = aves[:, :3].T
    stations_ecef = np.array(geo.toECEF(lon, lat, alt)).T

    center_ecef = np.array(geo.toECEF(center[1], center[0], center[2]))
    ordered_threshs = aves[:, -1]

    check = projl.fromECEF(stations_ecef[:, 0], stations_ecef[:, 1],
                           stations_ecef[:, 2])
    xmin = np.min(check[0]) - mindist
    xmax = np.max(check[0]) + mindist
    ymin = np.min(check[1]) - mindist
    ymax = np.max(check[1]) + mindist
    alts = np.array([altitude])
    initial_points = np.array(
        np.meshgrid(np.arange(xmin, xmax + xint, xint),
                    np.arange(ymin, ymax + xint, xint), alts))

    x, y, z = initial_points.reshape((3, int(np.size(initial_points) / 3)))
    points2 = np.array(projl.toECEF(x, y, z)).T

    xp, yp, zp = points2.T
    lonp, latp, zp = geo.fromECEF(xp, yp, zp)
    latp = latp.reshape(
        np.shape(initial_points)[1],
        np.shape(initial_points)[2])
    lonp = lonp.reshape(
        np.shape(initial_points)[1],
        np.shape(initial_points)[2])

    tanp_all = []
    for i in range(len(aves[:, 0])):
        tanp_all = tanp_all + [
            TangentPlaneCartesianSystem(aves[i, 0], aves[i, 1], aves[i, 2])
        ]

    masking2 = np.ma.empty((np.shape(stations_ecef)[0], np.shape(x)[0]))
    dt, ran = travel_time(points2, stations_ecef, c=c0, get_r=True)
    selection = np.sum(ran < 320000, axis=0) > 0
    for i in range(len(stations_ecef[:, 0])):
        masking2[i,
                 selection] = tanp_all[i].toLocal(points2[selection].T)[2] > 0

    ran = np.ma.masked_where(masking2 == 0, ran)
    ran = np.ma.masked_where(ran >= 320000, ran)

    mins = min_power((10**(ordered_threshs / 10.)) * 1e-3, ran)
    np.ma.set_fill_value(mins, 999)
    req_power = np.partition(mins.filled(), station_requirement - 1,
                             axis=0)[station_requirement - 1]

    sde = np.zeros_like(req_power)
    for i in range(len(sq[0]) - 1):
        selects = (req_power >= sq[1, i]) & (req_power < sq[1, i + 1])
        sde[selects] = 100 - sq[0, i + 1]

    selects = (req_power < sq[1, 0])
    sde[selects] = 100
    sde = (sde.T.reshape(np.shape(initial_points[0, :, :, 0])))

    fde_a = np.zeros_like(sde)
    xs = 1000. / np.arange(
        10, 1000, 1.
    )  # Theoretical source detection efficiency that corresponds with fde

    selects = sde == 100.  # Put into the next lowest or equivalent flash DE from given source DE
    fde_a[selects] = 100.
    for i in range(len(xs) - 1):
        selects = (sde >= xs[1 + i]) & (sde < xs[i])
        fde_a[selects] = fde[i]

    req_power = (req_power.T.reshape(np.shape(initial_points[0, :, :, 0])))

    return latp, lonp, sde, fde_a, req_power
Example #6
0
def grid_h5flashfiles(
    h5_filenames,
    start_time,
    end_time,
    frame_interval=120.0,
    dx=4.0e3,
    dy=4.0e3,
    x_bnd=(-100e3, 100e3),
    y_bnd=(-100e3, 100e3),
    z_bnd=(-20e3, 20e3),
    ctr_lat=35.23833,
    ctr_lon=-97.46028,
    min_points_per_flash=10,
    outpath='',
    flash_count_logfile=None,
    proj_name='aeqd',
    proj_datum='WGS84',
    proj_ellipse='WGS84',
    output_writer=write_cf_netcdf,
    output_filename_prefix="LMA",
    output_kwargs={},
    spatial_scale_factor=1.0 / 1000.0,
):
    from math import ceil
    """
    
    Create 2D plan-view density grids for events, flash origins, flash extents, and mean flash footprint
    
    frame_interval: Frame time-step in seconds
    dx, dy: horizontal grid size in m (or deg)
    {x,y,z}_bnd: horizontal grid edges in m
    ctr_lat, ctr_lon: coordinate center
    
    Uses an azimuthal equidistant map projection on the WGS84 ellipsoid.
    
    
    read_flashes
    
    filter_flash
    extract_events
    flash_to_frame
    
    frame0_broadcast, frame1_broadcast, ...
    
    each broadcaster above sends events and flashes to:
    projection( event_location), projection(flash_init_location), projection(event_location)
    which map respectively to:
    point_density->accum_on_grid(event density), point_density->accum_on_grid(flash init density), extent_density->accum_on_grid(flash_extent_density)

    grids are in an HDF5 file. how to handle flushing?
    """

    if flash_count_logfile is None:
        flash_count_logfile = sys.stdout

    # reference time is the date part of the start_time

    t_edges, duration = time_edges(start_time, end_time, frame_interval)
    t_ref, t_edges_seconds = seconds_since_start_of_day(start_time, t_edges)
    n_frames = len(t_edges) - 1

    xedge = np.arange(x_bnd[0], x_bnd[1] + dx, dx)
    yedge = np.arange(y_bnd[0], y_bnd[1] + dy, dy)

    x0 = xedge[0]
    y0 = yedge[0]

    if proj_name == 'latlong':
        dx_units = '{0:6.4f}deg'.format(dx)
        mapProj = GeographicSystem()
    else:
        dx_units = '{0:5.1f}m'.format(dx)
        mapProj = MapProjection(projection=proj_name,
                                ctrLat=ctr_lat,
                                ctrLon=ctr_lon,
                                lat_ts=ctr_lat,
                                lon_0=ctr_lon,
                                lat_0=ctr_lat,
                                lat_1=ctr_lat,
                                ellipse=proj_ellipse,
                                datum=proj_datum)
    geoProj = GeographicSystem()

    event_density_grid = np.zeros(
        (xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype='int32')
    init_density_grid = np.zeros(
        (xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype='int32')
    extent_density_grid = np.zeros(
        (xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype='int32')
    footprint_grid = np.zeros(
        (xedge.shape[0] - 1, yedge.shape[0] - 1, n_frames), dtype='float32')

    all_frames = []
    extent_frames = []
    init_frames = []
    event_frames = []
    for i in range(n_frames):
        extent_out = {'name': 'extent'}
        init_out = {'name': 'init'}
        event_out = {'name': 'event'}
        accum_event_density = density_to_files.accumulate_points_on_grid(
            event_density_grid[:, :, i],
            xedge,
            yedge,
            out=event_out,
            label='event')
        accum_init_density = density_to_files.accumulate_points_on_grid(
            init_density_grid[:, :, i],
            xedge,
            yedge,
            out=init_out,
            label='init')
        accum_extent_density = density_to_files.accumulate_points_on_grid(
            extent_density_grid[:, :, i],
            xedge,
            yedge,
            out=extent_out,
            label='extent')
        accum_footprint = density_to_files.accumulate_points_on_grid(
            footprint_grid[:, :, i], xedge, yedge, label='footprint')
        extent_out['func'] = accum_extent_density
        init_out['func'] = accum_init_density
        event_out['func'] = accum_event_density
        extent_frames.append(extent_out)
        init_frames.append(init_out)
        event_frames.append(event_out)

        event_density_target = density_to_files.point_density(
            accum_event_density)
        init_density_target = density_to_files.point_density(
            accum_init_density)
        extent_density_target = density_to_files.extent_density(
            x0, y0, dx, dy, accum_extent_density)
        mean_footprint_target = density_to_files.extent_density(
            x0, y0, dx, dy, accum_footprint, weight_key='area')

        spew_to_density_types = density_to_files.broadcast((
            density_to_files.project('lon',
                                     'lat',
                                     'alt',
                                     mapProj,
                                     geoProj,
                                     event_density_target,
                                     use_flashes=False),
            density_to_files.project('init_lon',
                                     'init_lat',
                                     'init_alt',
                                     mapProj,
                                     geoProj,
                                     init_density_target,
                                     use_flashes=True),
            density_to_files.project('lon',
                                     'lat',
                                     'alt',
                                     mapProj,
                                     geoProj,
                                     extent_density_target,
                                     use_flashes=False),
            density_to_files.project('lon',
                                     'lat',
                                     'alt',
                                     mapProj,
                                     geoProj,
                                     mean_footprint_target,
                                     use_flashes=False),
        ))

        all_frames.append(
            density_to_files.extract_events_for_flashes(spew_to_density_types))

    frame_count_log = density_to_files.flash_count_log(flash_count_logfile)

    framer = density_to_files.flashes_to_frames(t_edges_seconds,
                                                all_frames,
                                                time_key='start',
                                                time_edges_datetime=t_edges,
                                                flash_counter=frame_count_log)

    read_flashes(h5_filenames,
                 framer,
                 base_date=t_ref,
                 min_points=min_points_per_flash)

    # print 'event_density_grid ', id(event_density_grid[:,:,-1])
    # print 'extent_density_grid', id(extent_density_grid[:,:,-1])
    # print 'init_density_grid  ', id(init_density_grid[:,:,-1])

    x_coord = (xedge[:-1] + xedge[1:]) / 2.0
    y_coord = (yedge[:-1] + yedge[1:]) / 2.0
    nx = x_coord.shape[0]
    ny = y_coord.shape[0]

    x_all, y_all = (a.T for a in np.meshgrid(x_coord, y_coord))
    assert x_all.shape == y_all.shape
    assert x_all.shape[0] == nx
    assert x_all.shape[1] == ny
    z_all = np.zeros_like(x_all)

    lons, lats, alts = x, y, z = geoProj.fromECEF(
        *mapProj.toECEF(x_all, y_all, z_all))
    lons.shape = x_all.shape
    lats.shape = y_all.shape

    outflile_basename = os.path.join(
        outpath, '%s_%s_%d_%dsrc_%s-dx_' %
        (output_filename_prefix, start_time.strftime('%Y%m%d_%H%M%S'),
         to_seconds(duration), min_points_per_flash, dx_units))

    outfiles = (
        outflile_basename + 'flash_extent.nc',
        outflile_basename + 'flash_init.nc',
        outflile_basename + 'source.nc',
        outflile_basename + 'footprint.nc',
    )

    outgrids = (extent_density_grid, init_density_grid, event_density_grid,
                footprint_grid)

    field_names = ('flash_extent', 'flash_initiation', 'lma_source',
                   'flash_footprint')

    field_descriptions = ('LMA flash extent density',
                          'LMA flash initiation density', 'LMA source density',
                          'LMA local mean flash area')

    if proj_name == 'latlong':
        density_units = "grid"
    else:
        density_units = "{0:5.1f} km^2".format(dx / 1000.0 * dy /
                                               1000.0).lstrip()
    time_units = "{0:5.1f} min".format(frame_interval / 60.0).lstrip()
    density_label = 'Count per ' + density_units + " pixel per " + time_units

    field_units = (
        density_label,
        density_label,
        density_label,
        "km^2 per flash",
    )

    output_writer(outfiles[0],
                  t_ref,
                  np.asarray(t_edges_seconds[:-1]),
                  x_coord * spatial_scale_factor,
                  y_coord * spatial_scale_factor,
                  lons,
                  lats,
                  ctr_lat,
                  ctr_lon,
                  outgrids[0],
                  field_names[0],
                  field_descriptions[0],
                  grid_units=field_units[0],
                  **output_kwargs)
    output_writer(outfiles[1],
                  t_ref,
                  np.asarray(t_edges_seconds[:-1]),
                  x_coord * spatial_scale_factor,
                  y_coord * spatial_scale_factor,
                  lons,
                  lats,
                  ctr_lat,
                  ctr_lon,
                  outgrids[1],
                  field_names[1],
                  field_descriptions[1],
                  grid_units=field_units[1],
                  **output_kwargs)
    output_writer(outfiles[2],
                  t_ref,
                  np.asarray(t_edges_seconds[:-1]),
                  x_coord * spatial_scale_factor,
                  y_coord * spatial_scale_factor,
                  lons,
                  lats,
                  ctr_lat,
                  ctr_lon,
                  outgrids[2],
                  field_names[2],
                  field_descriptions[2],
                  grid_units=field_units[2],
                  **output_kwargs)
    output_writer(outfiles[3],
                  t_ref,
                  np.asarray(t_edges_seconds[:-1]),
                  x_coord * spatial_scale_factor,
                  y_coord * spatial_scale_factor,
                  lons,
                  lats,
                  ctr_lat,
                  ctr_lon,
                  outgrids[3],
                  field_names[3],
                  field_descriptions[3],
                  format='f',
                  grid_units=field_units[3],
                  **output_kwargs)

    print 'max extent is', extent_density_grid.max()

    return x_coord, y_coord, lons, lats, extent_density_grid, outfiles, field_names
Example #7
0
def dlonlat_at_grid_center(ctr_lat,
                           ctr_lon,
                           dx=4.0e3,
                           dy=4.0e3,
                           x_bnd=(-100e3, 100e3),
                           y_bnd=(-100e3, 100e3),
                           proj_datum='WGS84',
                           proj_ellipse='WGS84'):
    """ 
    
    Utility function useful for producing a regular grid of lat/lon data, 
    where an approximate spacing (dx, dy) and total span of the grid (x_bnd, y_bnd) 
    is desired. Units are in meters.
    
    There is guaranteed to be distortion away from the grid center, i.e.,
    only the grid cells adjacent to the center location will have area dx * dy. 
    
    Likewise, the lat, lon range is calculated naively using dlat, dlon multiplied
    by the number of grid cells implied by x_bnd/dx, y_bnd/dy. This is the naive approach,
    but probably what's expected when specifying distances in kilometers for
    an inherently distorted lat/lon grid.
    
    Returns: 
    (dlon, dlat, lon_bnd, lat_bnd)
    corresponding to 
    (dx, dy, x_range, y_range)
    
    """

    # Use the Azimuthal equidistant projection as the method for converting to kilometers.
    proj_name = 'aeqd'

    mapProj = MapProjection(projection=proj_name,
                            ctrLat=ctr_lat,
                            ctrLon=ctr_lon,
                            lat_ts=ctr_lat,
                            lon_0=ctr_lon,
                            lat_0=ctr_lat,
                            lat_1=ctr_lat,
                            ellipse=proj_ellipse,
                            datum=proj_datum)
    geoProj = GeographicSystem()

    # Get dlat
    lon_n, lat_n, z_n = geoProj.fromECEF(*mapProj.toECEF(0, dy, 0))
    dlat = lat_n - ctr_lat

    # Get dlon
    lon_e, lat_e, z_e = geoProj.fromECEF(*mapProj.toECEF(dx, 0, 0))
    dlon = lon_e - ctr_lon

    lon_min = ctr_lon + dlon * (x_bnd[0] / dx)
    lon_max = ctr_lon + dlon * (x_bnd[1] / dx)
    lat_min = ctr_lat + dlat * (y_bnd[0] / dy)
    lat_max = ctr_lat + dlat * (y_bnd[1] / dy)

    # Alternate method: lat lon for the actual distance to the NSEW in the projection
    #lon_range_n, lat_range_n, z_range_n = geoProj.fromECEF(*mapProj.toECEF(0,y_bnd,0))
    #lon_range_e, lat_range_e, z_range_e = geoProj.fromECEF(*mapProj.toECEF(x_bnd,0,0))

    return dlon, dlat, (lon_min, lon_max), (lat_min, lat_max)