Beispiel #1
0
def zsample(d, zres=None, zlim=None):
    b = d['backscatter']
    if 'backscatter_mol' in d:
        bmol = d['backscatter_mol']
    if len(b.shape) == 3:
        n, m, l = b.shape
        dims = (n, m, l)
    else:
        n, m = b.shape
        l = 0
        dims = (n, m)
    dims_mol = (n, m)
    b_sd = d['backscatter_sd'] if 'backscatter_sd' in d \
     else np.zeros(dims, dtype=np.float64)
    zfull = d['zfull']
    zhalf = np.zeros((n, m + 1), dtype=np.float64)
    for i in range(n):
        zhalf[i,:] = misc.half(zfull[i,:]) \
         if zfull.ndim == 2 \
         else misc.half(zfull)
    r = d['range'] if 'range' in d \
     else np.zeros(m, dtype=np.float64)
    if m == 0:
        return
    zhalf2 = np.arange(zlim[0], zlim[-1] + zres, zres)
    zfull2 = (zhalf2[1:] + zhalf2[:-1]) * 0.5
    m2 = len(zfull2)
    dims2 = (n, m2, l) if len(b.shape) == 3 else (n, m2)
    dims_mol2 = (n, m2)
    b2 = np.zeros(dims2, dtype=np.float64)
    b_sd2 = np.zeros(dims2, dtype=np.float64)
    bmol2 = np.zeros(dims_mol2, dtype=np.float64)
    # r2 = np.zeros(m2, dtype=np.float64)
    if l == 0:
        for i in range(n):
            b2[i, :] = interp(zhalf[i, :], b[i, :], zhalf2)
            b_sd2[i, :] = interp(zhalf[i, :], b_sd[i, :], zhalf2)
    else:
        for i in range(n):
            for j in range(l):
                b2[i, :, j] = interp(zhalf[i, :], b[i, :, j], zhalf2)
                b_sd2[i, :, j] = interp(zhalf[i, :], b_sd[i, :, j], zhalf2)
    if 'backscatter_mol' in d:
        for i in range(n):
            bmol2[i, :] = interp(zhalf[i, :], bmol[i, :], zhalf2)
    # d['range'] = r2
    d['zfull'] = zfull2
    d['backscatter'] = b2
    if 'backscatter_mol' in d:
        d['backscatter_mol'] = bmol2
    if 'backscatter_sd' in d:
        d['backscatter_sd'] = b_sd2
    d['.']['zfull']['.dims'] = ['level']
Beispiel #2
0
def couple(d, d_idx):
    dims = d['backscatter'].shape
    n = dims[0]
    l = dims[2] if len(dims) == 3 else 0
    couple_bsd = False
    couple_bmol = False
    if 'backscatter_sd' not in d:
        couple_bsd = True
        d['backscatter_sd'] = np.full(dims, np.nan, np.float64)
        d['.']['backscatter_sd'] = {
         '.dims': ['time', 'range', 'column'] \
          if len(dims) == 3 \
          else ['time', 'range'],
         'long_name': 'total_attenuated_backscatter_coefficient_standard_deviation',
         'units': 'm-1 sr-1',
        }
    if 'backsatter_mol' not in d:
        couple_bmol = True
        d['backscatter_mol'] = np.full(dims, np.nan, np.float64)
        d['.']['backscatter_mol'] = {
         '.dims': ['time', 'range', 'column'] \
          if len(dims) == 3 \
          else ['time', 'range'],
         'long_name': 'total_attenuated_molecular_backscatter_coefficient',
         'units': 'm-1 sr-1',
        }
    for i in range(n):
        t = d['time'][i]
        j = np.argmin(np.abs(d_idx['time'] - t))
        n1 = d_idx['n'][j]
        filename = d_idx['filename'][n1]
        i1 = d_idx['i'][j]
        d1 = ds.read(filename, VARIABLES, {'time': i1})
        zhalf1 = misc.half(d1['zfull'])
        zhalf = misc.half(d['zfull'][i,:]) \
         if d['zfull'].ndim == 2 \
         else misc.half(d['zfull'])
        if couple_bsd and 'backscatter_sd' in d1:
            b_sd = interp(zhalf1, d1['backscatter_sd'], zhalf)
            if len(dims) == 3:
                for k in range(l):
                    d['backscatter_sd'][i, :, k] = b_sd
            else:
                d['backscatter_sd'][i, :] = b_sd
        if couple_bmol and 'backscatter_mol' in d1:
            b_mol = interp(zhalf1, d1['backscatter_mol'], zhalf)
            if len(dims) == 3:
                for k in range(l):
                    d['backscatter_mol'][i, :, k] = b_mol
            else:
                d['backscatter_mol'][i, :] = b_mol
Beispiel #3
0
def couple(d, d_idx):
    n, m, l = d['backscatter'].shape
    d['backscatter_sd'] = np.full((n, m, l), np.nan, np.float64)
    d['.']['backscatter_sd'] = {
        '.dims': ['time', 'range', 'column'],
        'long_name':
        'total_attenuated_backscatter_coefficient_standard_deviation',
        'units': 'm-1 sr-1',
    }
    for i in range(n):
        t = d['time'][i]
        j = np.argmin(np.abs(d_idx['time'] - t))
        n1 = d_idx['n'][j]
        filename = d_idx['filename'][n1]
        i1 = d_idx['i'][j]
        d1 = ds.read(filename, ['zfull', 'backscatter_sd'], {'time': i1})
        zhalf1 = misc.half(d1['zfull'])
        zhalf = misc.half(d['zfull'][i, :])
        b_sd = interp(zhalf1, d1['backscatter_sd'], zhalf)
        for k in range(l):
            d['backscatter_sd'][i, :, k] = b_sd
Beispiel #4
0
def plot_profile(plot_type,
                 d,
                 cax=None,
                 subcolumn=0,
                 sigma=5,
                 remove_bmol=True,
                 vlim=None,
                 vlog=None,
                 zres=50,
                 zlim=None,
                 **opts):
    if plot_type == 'backscatter':
        cmap = copy.copy(mpl.cm.get_cmap('viridis'))
        under = '#222222'
        label = 'Att. vol. backscattering coef. (×10$^{-6}$ m$^{-1}$sr$^{-1}$)'
        if vlim is None:
            vlim = [0.1, 200]
        if vlog is None:
            vlog = True
        if len(d['backscatter'].shape) == 3:
            b = d['backscatter'][:, :, subcolumn]
            cloud_mask = d['cloud_mask'][:, :, subcolumn]
            bsd = d['backscatter_sd'][:,:,subcolumn] if 'backscatter_sd' in d \
             else np.zeros(b.shape, dtype=np.float64)
        else:
            b = d['backscatter']
            cloud_mask = d['cloud_mask']
            bsd = d['backscatter_sd'] if 'backscatter_sd' in d \
             else np.zeros(b.shape, dtype=np.float64)
        if sigma > 0:
            b -= sigma * bsd
        if remove_bmol and 'backscatter_mol' in d:
            bmol = d['backscatter_mol']
            mask = ~np.isnan(bmol)
            b[mask] -= bmol[mask]
        x = b * 1e6
        x[x <= 0.] = 0.5 * vlim[0]  # A value below the limit.
        time = d['time']
        zfull = d['zfull']
    elif plot_type in ('clw', 'cli', 'cl'):
        cmap = copy.copy(
            mpl.cm.get_cmap({
                'clw': 'Reds',
                'cli': 'Blues',
                'cl': 'Greys_r',
            }[plot_type]))
        under = {
            'clw': 'white',
            'cli': 'white',
            'cl': 'k',
        }[plot_type]
        label = {
            'clw': 'Cloud water (g/kg)',
            'cli': 'Cloud ice (g/kg)',
            'cl': 'Cloud fraction (%)',
        }[plot_type]
        if vlim is None:
            vlim = {
                'clw': [1e-3, 1],
                'cli': [1e-3, 1],
                'cl': [0, 100],
            }[plot_type]
        if vlog is None:
            vlog = {'clw': True, 'cli': True, 'cl': False}[plot_type]
        x = d[plot_type]
        if plot_type in ('clw', 'cli', 'clw+cli'):
            x *= 1e3
        if x.shape == 3:
            x = x[:, :, subcolumn]
        if zlim is None:
            zlim = [np.min(d['zfull']), np.max(d['zfull'])]
        zhalf = np.arange(zlim[0], zlim[1] + zres, zres)
        zfull = 0.5 * (zhalf[1:] + zhalf[:-1])
        xp = np.full((x.shape[0], len(zfull)), np.nan, np.float64)
        for i in range(xp.shape[0]):
            zhalfi = misc.half(d['zfull'][i, :])
            xp[i, :] = algorithms.interp(zhalfi, x[i, :], zhalf)
        x = xp
        time = d['time']
    else:
        raise ValueError('Invalid plot type "%s"' % plot_type)

    if vlog:
        norm = LogNorm(vlim[0], vlim[1])
    else:
        norm = Normalize(vlim[0], vlim[1])

    t1 = time[0] - 0.5 * (time[1] - time[0])
    t2 = time[-1] + 0.5 * (time[-1] - time[-2])
    z1 = zfull[0] - 0.5 * (zfull[1] - zfull[0])
    z2 = zfull[-1] + 0.5 * (zfull[-1] - zfull[-2])

    im = plt.imshow(
        x.T,
        extent=(t1, t2, z1 * 1e-3, z2 * 1e-3),
        aspect='auto',
        origin='lower',
        norm=norm,
        cmap=cmap,
    )
    im.cmap.set_under(under)

    cb = plt.colorbar(
        cax=cax,
        label=label,
        pad=0.03,
        fraction=0.05,
        aspect='auto',
        extend='both',
    )

    if zlim is not None:
        plt.ylim(zlim[0] * 1e-3, zlim[1] * 1e-3)

    plt.xlabel('Time (UTC)')
    plt.ylabel('Height (km)')

    formatter = plt.FuncFormatter(lambda t, p: \
     aq.to_datetime(t).strftime('%d/%m\n%H:%M'))
    locator = AutoDateLocator()
    plt.gca().xaxis.set_major_formatter(formatter)
    plt.gca().xaxis.set_major_locator(locator)

    if plot_type == 'backscatter' and opts.get('cloud_mask'):
        cf = plt.contour(
            d['time'],
            d['zfull'] * 1e-3,
            cloud_mask.T,
            colors='red',
            linewidths=1,
            linestyles='dashed',
            levels=[-1., 0.5, 2.],
        )
        plot_legend(handles=[
            mlines.Line2D([], [],
                          color='red',
                          linestyle='dashed',
                          label='Cloud mask')
        ],
                    theme='dark')

    if 'altitude' in d:
        plt.plot(d['time'], d['altitude'] * 1e-3, color='red', lw=0.5)
Beispiel #5
0
def stats_map(d,
              state,
              tlim=None,
              blim=None,
              bres=None,
              bsd_lim=None,
              bsd_log=None,
              bsd_res=None,
              bsd_z=None,
              filter=None,
              zlim=None,
              zres=None,
              **kwargs):
    if zlim is not None and zres is not None:
        state['zfull2'] = state.get(
            'zfull2', np.arange(zlim[0] + 0.5 * zres, zlim[1], zres))
    else:
        state['zfull2'] = state.get('zfull2', d['zfull'])
    zhalf = misc.half(d['zfull'])
    zhalf2 = misc.half(state['zfull2'])
    state['backscatter_half'] = state.get(
        'backscatter_half', np.arange(blim[0], blim[1] + bres, bres))
    state['backscatter_full'] = state.get(
        'backscatter_full',
        0.5 * (state['backscatter_half'][1:] + state['backscatter_half'][:-1]))
    o = len(state['backscatter_full'])
    state['backscatter_sd_half'] = state.get('backscatter_sd_half',
     np.exp(np.arange(np.log(bsd_lim[0]), np.log(bsd_lim[1] + bsd_res),
      np.log(bsd_lim[0] + bsd_res) - np.log(bsd_lim[0])))
     if bsd_log is True \
     else np.arange(bsd_lim[0], bsd_lim[1] + bsd_res, bsd_res)
    )
    state['backscatter_sd_full'] = state.get(
        'backscatter_sd_full', 0.5 *
        (state['backscatter_sd_half'][1:] + state['backscatter_sd_half'][:-1]))
    osd = len(state['backscatter_sd_full'])
    m2 = len(state['zfull2'])
    if len(d['cloud_mask'].shape) == 3:
        n, m, l = d['cloud_mask'].shape
        dims = (m, l)
        dims2 = (m2, l)
        hist_dims = (o, m, l)
        hist_dims2 = (o, m2, l)
        sd_hist_dims = (osd, l)
        filter_mask_dims = (n, l)
    else:
        n, m = d['cloud_mask'].shape
        l = 0
        dims = (m, )
        dims2 = (m2, )
        hist_dims = (o, m)
        hist_dims2 = (o, m2)
        sd_hist_dims = (osd, )
        filter_mask_dims = (n, )
    state['n'] = state.get('n', 0 if l == 0 else np.zeros(l, dtype=np.int64))
    state['backscatter_avg'] = state.get('backscatter_avg',
                                         np.zeros(dims2, dtype=np.float64))
    state['backscatter_mol_avg'] = state.get('backscatter_mol_avg',
                                             np.zeros(dims2, dtype=np.float64))
    state['cl'] = state.get('cl', np.zeros(dims2, dtype=np.float64))
    state['clt'] = state.get('clt',
                             np.zeros(l, dtype=np.float64) if l > 0 else 0)
    state['backscatter_hist'] = state.get(
        'backscatter_hist', np.zeros(hist_dims2, dtype=np.float64))
    state['backscatter_sd_hist'] = state.get(
        'backscatter_sd_hist', np.zeros(sd_hist_dims, dtype=np.float64))
    backscatter_hist_tmp = np.zeros(hist_dims, dtype=np.float64)
    cl_tmp = np.zeros(dims, dtype=np.float64)
    clt_tmp = np.zeros(l, dtype=np.float64) if l > 0 else 0
    backscatter_avg_tmp = np.zeros(dims, dtype=np.float64)
    backscatter_mol_avg_tmp = np.zeros(dims, dtype=np.float64)
    if tlim is not None:
        mask = (d['time'] >= tlim[0]) & (d['time'] < tlim[1])
    else:
        mask = np.ones(n, dtype=np.bool)

    if l > 0:
        mask &= np.all(~np.isnan(d['backscatter']), axis=(1, 2))
    else:
        mask &= np.all(~np.isnan(d['backscatter']), axis=(1, ))

    filter_mask = np.ones(filter_mask_dims, dtype=np.bool)
    if 'cloudy' in filter:
        filter_mask &= np.any(d['cloud_mask'], axis=1)
    if 'clear' in filter:
        filter_mask &= ~np.any(d['cloud_mask'], axis=1)
    if 'day' in filter:
        filter_mask_0 = misc.sun_altitude(d['time'], d['lon'], d['lat']) >= 0
        if l > 0: filter_mask_0 = np.tile(filter_mask_0, [l, 1]).T
        filter_mask &= filter_mask_0
    if 'night' in filter:
        filter_mask_0 = misc.sun_altitude(d['time'], d['lon'], d['lat']) < 0
        if l > 0: filter_mask_0 = np.tile(filter_mask_0, [l, 1]).T
        filter_mask &= filter_mask_0

    if not np.any(mask):
        return
    for j in range(m):
        if l > 0:
            for k in range(l):
                backscatter_hist_tmp[:, j, k] += np.histogram(
                    d['backscatter'][filter_mask[:, k] & mask, j, k],
                    bins=state['backscatter_half'])[0]
        else:
            backscatter_hist_tmp[:, j] += np.histogram(
                d['backscatter'][filter_mask & mask, j],
                bins=state['backscatter_half'])[0]

    jsd = np.argmin(np.abs(d['zfull'] - bsd_z))
    state['backscatter_sd_z'] = d['zfull'][jsd]

    if 'backscatter_sd' in d:
        if l > 0:
            for k in range(l):
                state['backscatter_sd_hist'][:, k] += np.histogram(
                    d['backscatter_sd'][filter_mask[:, k] & mask, jsd, k],
                    bins=state['backscatter_sd_half'])[0]
        else:
            state['backscatter_sd_hist'] += np.histogram(
                d['backscatter_sd'][filter_mask & mask, jsd],
                bins=state['backscatter_sd_half'])[0]

    for i in range(o):
        if l > 0:
            for k in range(l):
                state['backscatter_hist'][i, :, k] += interp(
                    zhalf, backscatter_hist_tmp[i, :, k], zhalf2)
        else:
            state['backscatter_hist'][i, :] += interp(
                zhalf, backscatter_hist_tmp[i, :], zhalf2)
    for i in range(n):
        if not mask[i]:
            continue
        if l > 0:
            for k in range(l):
                if not filter_mask[i, k]:
                    continue
                cl_tmp[:, k] += d['cloud_mask'][i, :, k]
                backscatter_avg_tmp[:, k] += d['backscatter'][i, :, k]
                if 'backscatter_mol' in d:
                    backscatter_mol_avg_tmp[:, k] += d['backscatter_mol'][i, :]
                state['n'][k] += 1
                state['clt'][k] += np.any(d['cloud_mask'][i, :, k])
        else:
            if not filter_mask[i]:
                continue
            cl_tmp[:] += d['cloud_mask'][i, :]
            backscatter_avg_tmp[:] += d['backscatter'][i, :]
            if 'backscatter_mol' in d:
                backscatter_mol_avg_tmp[:] += d['backscatter_mol'][i, :]
            state['n'] += 1
            state['clt'] += np.any(d['cloud_mask'][i, :])
    if l > 0:
        for k in range(l):
            state['cl'][:, k] += interp(zhalf, cl_tmp[:, k], zhalf2)
            state['backscatter_avg'][:, k] += interp(zhalf,
                                                     backscatter_avg_tmp[:, k],
                                                     zhalf2)
            state['backscatter_mol_avg'][:, k] += interp(
                zhalf, backscatter_mol_avg_tmp[:, k], zhalf2)
    else:
        state['cl'] += interp(zhalf, cl_tmp, zhalf2)
        state['backscatter_avg'] += interp(zhalf, backscatter_avg_tmp, zhalf2)
        state['backscatter_mol_avg'] += interp(zhalf, backscatter_mol_avg_tmp,
                                               zhalf2)