def main(inargs):
    """Run the program."""

    # Read the data
    dset_in = xarray.open_dataset(inargs.infile)
    gio.check_xarrayDataset(dset_in, inargs.variable)

    subset_dict = gio.get_subset_kwargs(inargs)
    darray = dset_in[inargs.variable].sel(**subset_dict)

    # Calculate the zonal anomaly
    zonal_mean = darray.mean(dim='longitude')
    zonal_anomaly = darray - zonal_mean

    # Write output file
    d = {}
    for dim in darray.dims:
        d[dim] = darray[dim]
    d[inargs.variable] = (darray.dims, zonal_anomaly)

    dset_out = xarray.Dataset(d)

    dset_out[inargs.variable].attrs = {
        'long_name': darray.attrs['long_name'],
        'standard_name': darray.attrs['standard_name'],
        'units': darray.attrs['units'],
        'notes': 'The zonal mean has been subtracted at each time step.'
    }

    gio.set_global_atts(dset_out, dset_in.attrs, {
        inargs.infile: dset_in.attrs['history'],
    })
    dset_out.to_netcdf(inargs.outfile, format='NETCDF3_CLASSIC')
def calc_zw3(ifile, var_id, ofile):
    """Calculate an index of the Southern Hemisphere ZW3 pattern.
    
    Ref: Raphael (2004). A zonal wave 3 index for the Southern Hemisphere. 
      Geophysical Research Letters, 31(23), L23212. 
      doi:10.1029/2004GL020365.

    Expected input: Raphael (2004) uses is the 500hPa geopotential height, 
      sea level pressure or 500hPa zonal anomalies which are constructed by 
      removing the zonal mean of the geopotential height from each grid point 
      (preferred). The running mean (and zonal mean too if using it) should 
      have been applied to the input data beforehand. Raphael (2004) uses a 
      3-month running mean.

    Design notes: This function uses cdo instead of CDAT because the
      cdutil library doesn't have routines for calculating the daily 
      climatology or stdev.
    
    """

    # Read data
    dset_in = xarray.open_dataset(ifile)
    gio.check_xarrayDataset(dset_in, var_id)

    # Calculate the index
    groupby_op = get_groupby_op(dset_in['time'].values)
    index = {}
    for region in ['zw31', 'zw32', 'zw33']:
        south_lat, north_lat, west_lon, east_lon = gio.regions[region]
        darray = dset_in[var_id].sel(
            latitude=slice(south_lat, north_lat),
            longitude=slice(west_lon,
                            east_lon)).mean(dim=['latitude', 'longitude'])

        clim = darray.groupby(groupby_op).mean(dim='time')
        anom = darray.groupby(groupby_op) - clim
        stdev = darray.groupby(groupby_op).std(dim='time')
        norm = anom.groupby(groupby_op) / stdev

        index[region] = norm.values

    zw3_timeseries = (index['zw31'] + index['zw32'] + index['zw33']) / 3.0

    # Write output file
    d = {}
    d['time'] = darray['time']
    d['zw3'] = (['time'], zw3_timeseries)
    dset_out = xarray.Dataset(d)

    dset_out['zw3'].attrs = {
        'id': 'zw3',
        'long_name': 'zonal_wave_3_index',
        'standard_name': 'zonal_wave_3_index',
        'units': '',
        'notes': 'Ref: ZW3 index of Raphael (2004)'
    }

    gio.set_global_atts(dset_out, dset_in.attrs,
                        {ifile: dset_in.attrs['history']})
    dset_out.to_netcdf(ofile, format='NETCDF3_CLASSIC')
def calc_sam(ifile, var_id, ofile):
    """Calculate an index of the Southern Annular Mode.

    Ref: Gong & Wang (1999). Definition of Antarctic Oscillation index. 
      Geophysical Research Letters, 26(4), 459-462.
      doi:10.1029/1999GL900003

    Expected input: Mean sea level pressure data.

    Concept: Difference between the normalised zonal mean pressure 
      at 40S and 65S.

    """

    # Read data
    dset_in = xarray.open_dataset(ifile)
    gio.check_xarrayDataset(dset_in, var_id)

    # Calculate index
    north_lat = uconv.find_nearest(dset_in['latitude'].values, -40)
    south_lat = uconv.find_nearest(dset_in['latitude'].values, -65)
    darray = dset_in[var_id].sel(latitude=(south_lat,
                                           north_lat)).mean(dim='longitude')

    groupby_op = get_groupby_op(darray['time'].values)
    clim = darray.groupby(groupby_op).mean(dim='time')
    anom = darray.groupby(groupby_op) - clim
    stdev = darray.groupby(groupby_op).std(dim='time')
    norm = anom.groupby(groupby_op) / stdev

    sam_timeseries = norm.sel(latitude=north_lat).values - norm.sel(
        latitude=south_lat).values

    # Write output file
    d = {}
    d['time'] = darray['time']
    d['sam'] = (['time'], sam_timeseries)
    dset_out = xarray.Dataset(d)

    hx = 'Ref: Gong & Wang (1999). GRL, 26, 459-462. doi:10.1029/1999GL900003'
    dset_out['sam'].attrs = {
        'long_name': 'Southern_Annular_Mode_Index',
        'standard_name': 'Southern_Annular_Mode_Index',
        'units': '',
        'notes': hx
    }

    gio.set_global_atts(dset_out, dset_in.attrs,
                        {ifile: dset_in.attrs['history']})
    dset_out.to_netcdf(ofile, format='NETCDF3_CLASSIC')
Ejemplo n.º 4
0
def main(inargs):
    """Run the program."""

    # Read the data
    dset_in = xarray.open_dataset(inargs.infile)
    gio.check_xarrayDataset(dset_in, inargs.var)
    darray, long_name, units = extract_data(dset_in, inargs)

    # Perform task
    outdata_dict = {}
    if inargs.outtype == 'coefficients':
        outdata_dict = _get_coefficients(darray.values,
                                         darray['longitude'].values,
                                         inargs.min_freq, inargs.max_freq,
                                         long_name, units, outdata_dict)
        if inargs.sign_change:
            outdata_dict = _get_sign_change(darray.values, outdata_dict)

        if inargs.env_max:
            env_max_min_freq, env_max_max_freq = inargs.env_max
            outdata_dict = _get_env_max(darray.values,
                                        darray['longitude'].values,
                                        env_max_min_freq, env_max_max_freq,
                                        units, outdata_dict)
        dims = darray.dims[:-1]
    else:
        outdata_dict = _filter_data(darray.values, darray['longitude'].values,
                                    inargs.min_freq, inargs.max_freq,
                                    inargs.var, long_name, units,
                                    inargs.outtype, outdata_dict)
        dims = darray.dims

    # Write the output file
    d = {}
    for dim in dims:
        d[dim] = darray[dim]

    for outvar in outdata_dict.keys():
        d[outvar] = (dims, outdata_dict[outvar][0])

    dset_out = xarray.Dataset(d)

    for outvar in outdata_dict.keys():
        dset_out[outvar].attrs = outdata_dict[outvar][1]

    gio.set_global_atts(dset_out, dset_in.attrs, {
        inargs.infile: dset_in.attrs['history'],
    })
    dset_out.to_netcdf(inargs.outfile)
def calc_nino(index, ifile, var_id, base_period, ofile):
    """Calculate a Nino index.

    Expected input: Sea surface temperature data.

    """

    index_name = 'nino' + index[4:]

    # Read the data
    dset_in = xarray.open_dataset(ifile)
    gio.check_xarrayDataset(dset_in, var_id)

    # Calculate the index
    south_lat, north_lat, west_lon, east_lon = gio.regions[index_name]
    darray = dset_in[var_id].sel(
        latitude=slice(south_lat, north_lat),
        longitude=slice(west_lon,
                        east_lon)).mean(dim=['latitude', 'longitude'])

    groupby_op = get_groupby_op(darray['time'].values)
    clim = darray.sel(
        time=slice(base_period[0], base_period[1])).groupby(groupby_op).mean()
    anom = darray.groupby(groupby_op) - clim

    # Write output
    if ofile:
        d = {}
        d['time'] = darray['time']
        d[index_name] = (['time'], anom.values)
        dset_out = xarray.Dataset(d)

        hx = 'lat: %s to %s, lon: %s to %s, base: %s to %s' % (
            south_lat, north_lat, west_lon, east_lon, base_period[0],
            base_period[1])

        dset_out[index_name].attrs = {
            'long_name': index_name + '_index',
            'standard_name': index_name + '_index',
            'units': 'Celsius',
            'notes': hx
        }

        gio.set_global_atts(dset_out, dset_in.attrs,
                            {ifile: dset_in.attrs['history']})
        dset_out.to_netcdf(ofile, format='NETCDF3_CLASSIC')
    else:
        return dset_in, anom.values
def calc_pwi(ifile, var_id, ofile):
    """Calculate the Planetary Wave Index.

    Ref: Irving & Simmonds (2015). A novel approach to diagnosing Southern 
      Hemisphere planetary wave activity and its influence on regional 
      climate variability. Journal of Climate. 28, 9041-9057. 
      doi:10.1175/JCLI-D-15-0287.1.
      
    Expected input: Wave envelope.   

    """

    # Read data
    dset_in = xarray.open_dataset(ifile)
    gio.check_xarrayDataset(dset_in, var_id)

    # Calculate index
    darray = dset_in[var_id].sel(latitude=slice(-70, -40))
    mermax = darray.max(dim='latitude')
    pwi_timeseries = mermax.median(dim='longitude')

    # Write output file
    d = {}
    d['time'] = darray['time']
    d['pwi'] = (['time'], pwi_timeseries.values)
    dset_out = xarray.Dataset(d)

    dset_out['pwi'].attrs = {
        'long_name': 'planetary_wave_index',
        'standard_name': 'planetary_wave_index',
        'units': darray.attrs['units'],
        'notes': 'Ref: PWI of Irving and Simmonds (2015)'
    }

    gio.set_global_atts(dset_out, dset_in.attrs,
                        {ifile: dset_in.attrs['history']})
    dset_out.to_netcdf(ofile, format='NETCDF3_CLASSIC')
def calc_mi(ifile, var_id, ofile):
    """Calculate the meridional wind index.

    Represents the average amplitude of the meridional wind
    over the 70S to 40S latitude band.
      
    Expected input: Meridional wind

    """

    # Read data
    dset_in = xarray.open_dataset(ifile)
    gio.check_xarrayDataset(dset_in, var_id)

    # Calculate index
    darray = dset_in[var_id].sel(latitude=slice(-70, -40))
    units = darray.attrs['units']

    darray = (darray**2)**0.5  # absolute value
    mi_timeseries = darray.mean(dim=['latitude', 'longitude'])

    # Write output file
    d = {}
    d['time'] = darray['time']
    d['pwi'] = (['time'], mi_timeseries.values)
    dset_out = xarray.Dataset(d)

    dset_out['pwi'].attrs = {
        'long_name': 'meridional_wind_index',
        'standard_name': 'meridional_wind_index',
        'units': units,
        'notes': 'Average amplitude of meridional wind over 70S to 40S'
    }

    gio.set_global_atts(dset_out, dset_in.attrs,
                        {ifile: dset_in.attrs['history']})
    dset_out.to_netcdf(ofile, format='NETCDF3_CLASSIC')
def calc_asl(ifile, var_id, ofile):
    """Calculate the Amundsen Sea Low index.

    Ref: Turner et al (2013). The Amundsen Sea Low. 
      International Journal of Climatology. 33(7), 1818-1829
      doi:10.1002/joc.3558.

    Expected input: Mean sea level pressure data.

    Concept: Location and value of minimum MSLP is the region
      bounded by 60-75S and 180-310E.   

    """

    # Read data
    dset_in = xarray.open_dataset(ifile)
    gio.check_xarrayDataset(dset_in, var_id)

    south_lat, north_lat, west_lon, east_lon = gio.regions['asl']
    darray = dset_in[var_id].sel(latitude=slice(south_lat, north_lat),
                                 longitude=slice(west_lon, east_lon))

    assert darray.dims == ('time', 'latitude', 'longitude'), \
    "Order of the data must be time, latitude, longitude"

    # Get axis information
    lat_values = darray['latitude'].values
    lon_values = darray['longitude'].values
    lats, lons = uconv.coordinate_pairs(lat_values, lon_values)

    # Reshape data
    ntimes, nlats, nlons = darray.values.shape
    darray_reshaped = numpy.reshape(darray.values, (ntimes, nlats * nlons))

    # Get the ASL index info (min value for each timestep and its lat/lon)
    min_values = numpy.amin(darray_reshaped, axis=1)
    min_indexes = numpy.argmin(darray_reshaped, axis=1)
    min_lats = numpy.take(lats, min_indexes)
    min_lons = numpy.take(lons, min_indexes)

    # Write the output file
    d = {}
    d['time'] = darray['time']
    d['asl_value'] = (['time'], min_values)
    d['asl_lat'] = (['time'], min_lats)
    d['asl_lon'] = (['time'], min_lons)
    dset_out = xarray.Dataset(d)

    ref = 'Ref: Turner et al (2013). Int J Clim. 33, 1818-1829. doi:10.1002/joc.3558.'
    dset_out['asl_value'].attrs = {
        'long_name': 'asl_minimum_pressure',
        'standard_name': 'asl_minimum_pressure',
        'units': 'Pa',
        'notes': ref
    }
    dset_out['asl_lat'].attrs = {
        'long_name': 'asl_latitude',
        'standard_name': 'asl_latitude',
        'units': 'degrees_north',
        'notes': ref
    }
    dset_out['asl_lon'].attrs = {
        'long_name': 'asl_longitude',
        'standard_name': 'asl_longitude',
        'units': 'degrees_east',
        'notes': ref
    }

    gio.set_global_atts(dset_out, dset_in.attrs,
                        {ifile: dset_in.attrs['history']})
    dset_out.to_netcdf(ofile, format='NETCDF3_CLASSIC')