Пример #1
0
	def add_times(cube, time):
		coord_cat.add_month(cube, time, name='month')
		coord_cat.add_season(cube, time, name='clim_season')
		coord_cat.add_year(cube, time, name='year')
		coord_cat.add_day_of_year(cube, time, name='day_number')
		coord_cat.add_season_year(cube, time, name='season_year')
		return cube
Пример #2
0
    def _clean_loaded_data(self):
        

        for i in range(len(self.data)):
            self.data[i].metadata.attributes.clear()
            self.data[i].coord("latitude").points=\
                self.data[i].coord("latitude").points.astype(np.float32)
            self.data[i].coord("longitude").points=\
                self.data[i].coord("longitude").points.astype(np.float32)
            
        self.data=self.data.concatenate_cube()
        try:
            self.data.coord(self.T).convert_units(self.U)
        except:
            print(f"Warning: could not convert {self.T} to {self.U}, simply renaming calendar.")
            new_T=cf_units.Unit(self.data.coord(self.T).units.origin,self.U.calendar)
            self.data.coord(self.T).units=new_T
            try:
                self.data.coord(self.T).convert_units(self.U)
            except:
                raise(ValueError("Unsuccesful attempt to change time units."))
        
        iccat.add_hour(self.data,self.T)
        self.data=self.data.extract(self.constraints["hour"])

        iccat.add_day_of_year(self.data,self.T)
        self.data=self.data.extract(self.constraints["calendar"])
        self.data=iris.cube.CubeList([self.data])
Пример #3
0
    def _clean_loaded_data(self):
        
        CL=iris.cube.CubeList()
        for i,cube in enumerate(self.data):
            for entry in cube.slices_over(self.T):
                
                entry.coord(self.T).convert_units(self.U)
                entry.coord(self.S).convert_units(cf_units.Unit("Days"))

                T_ref=entry.coord(self.T)
                S=entry.coord(self.S).points
                t_coord=iris.coords.AuxCoord(S+T_ref.points[0],standard_name="time")
                t_coord.units=T_ref.units
                entry.add_aux_coord(t_coord,data_dims=1)
                
                iccat.add_hour(entry,"time")
                iccat.add_day_of_year(entry,"time")

                CL.append(entry)
        CL.sort(key=lambda cube:cube.coord(self.T).points[0])            
        self.data=CL
        
        self.data=self.data.extract(self.constraints["calendar"])
        self.data=self.data.extract(self.constraints["lead"])
        self.data=self.data.extract(self.constraints["hour"])
        self.data=self.data.extract(self.constraints["ens"])
 def test_calendars(self):
     for calendar in calendars:
         cube = self.make_cube(calendar)
         add_day_of_year(cube, 'time')
         points = cube.coord('day_of_year').points
         expected_points = self.expected[calendar]
         msg = 'Test failed for the following calendar: {}.'
         self.assertArrayEqual(points, expected_points,
                               err_msg=msg.format(calendar))
Пример #5
0
 def test_calendars(self):
     for calendar in calendars:
         cube = self.make_cube(calendar)
         add_day_of_year(cube, 'time')
         points = cube.coord('day_of_year').points
         expected_points = self.expected[calendar]
         msg = 'Test failed for the following calendar: {}.'
         self.assertArrayEqual(points, expected_points,
                               err_msg=msg.format(calendar))
Пример #6
0
 def test_calendars(self):
     for calendar in calendars:
         # Skip the Julian calendar due to
         # https://github.com/Unidata/netcdftime/issues/13
         # Remove this if block once the issue is resolved.
         if calendar == 'julian':
             continue
         cube = self.make_cube(calendar)
         add_day_of_year(cube, 'time')
         points = cube.coord('day_of_year').points
         expected_points = self.expected[calendar]
         msg = 'Test failed for the following calendar: {}.'
         self.assertArrayEqual(points, expected_points,
                               err_msg=msg.format(calendar))
Пример #7
0
 def test_calendars(self):
     for calendar in calendars:
         # Skip the Julian calendar due to
         # https://github.com/Unidata/netcdftime/issues/13
         # Remove this if block once the issue is resolved.
         if calendar == "julian":
             continue
         cube = self.make_cube(calendar)
         add_day_of_year(cube, "time")
         points = cube.coord("day_of_year").points
         expected_points = self.expected[calendar]
         msg = "Test failed for the following calendar: {}."
         self.assertArrayEqual(points,
                               expected_points,
                               err_msg=msg.format(calendar))
 def _add_nan_timesteps(cube, total_days):
     add_day_of_year(cube, 'time')
     cubes = CubeList(cube.slices_over('time'))
     model_cube = cubes[0].copy()
     model_cube.remove_coord('day_of_year')
     for day_of_year in range(total_days):
         day_constraint = iris.Constraint(day_of_year=day_of_year + 1)
         if cubes.extract(day_constraint):
             continue
         nan_cube = OSICmorizer._create_nan_cube(model_cube,
                                                 day_of_year,
                                                 month=False)
         add_day_of_year(nan_cube, 'time')
         cubes.append(nan_cube)
     del model_cube
     return cubes
Пример #9
0
    def test_basic(self):
        cube = self.cube
        time_coord = self.time_coord

        ccat.add_year(cube, time_coord, 'my_year')
        ccat.add_day_of_month(cube, time_coord, 'my_day_of_month')
        ccat.add_day_of_year(cube, time_coord, 'my_day_of_year')

        ccat.add_month(cube, time_coord, 'my_month')
        with warnings.catch_warnings(record=True):
            ccat.add_month_shortname(cube, time_coord, 'my_month_shortname')
        ccat.add_month_fullname(cube, time_coord, 'my_month_fullname')
        ccat.add_month_number(cube, time_coord, 'my_month_number')

        ccat.add_weekday(cube, time_coord, 'my_weekday')
        ccat.add_weekday_number(cube, time_coord, 'my_weekday_number')
        with warnings.catch_warnings(record=True):
            ccat.add_weekday_shortname(cube, time_coord,
                                       'my_weekday_shortname')
        ccat.add_weekday_fullname(cube, time_coord, 'my_weekday_fullname')

        ccat.add_season(cube, time_coord, 'my_season')
        ccat.add_season_number(cube, time_coord, 'my_season_number')
        with warnings.catch_warnings(record=True):
            ccat.add_season_month_initials(cube, time_coord,
                                           'my_season_month_initials')
        ccat.add_season_year(cube, time_coord, 'my_season_year')

        # also test 'generic' categorisation interface
        def _month_in_quarter(coord, pt_value):
            date = coord.units.num2date(pt_value)
            return (date.month - 1) % 3

        ccat.add_categorised_coord(cube,
                                   'my_month_in_quarter',
                                   time_coord,
                                   _month_in_quarter)

        # To ensure consistent results between 32-bit and 64-bit
        # platforms, ensure all the numeric categorisation coordinates
        # are always stored as int64.
        for coord in cube.coords():
            if coord.long_name is not None and coord.points.dtype.kind == 'i':
                coord.points = coord.points.astype(np.int64)

        # check values
        self.assertCML(cube, ('categorisation', 'quickcheck.cml'))
def fix_sst_based_on_siconc(sst, ice, mean_freq_sice, im):
    '''
    Loop through ice concentration bins
    Find points in which ice concentration is near to this bin
    Only do this when the sea-ice conc is > 60% (we don't whant to effect the edge, just the Arctic to remove the stripes
    '''
    lat_size = ice.shape[1]
    ice_min_change_nh = 75.0
    ice_min_change_sh = 75.0

    start_bin = int(ice_min_change_nh / BIN['SICE']['SIZE']) - 1

    coord_names = [coord.name() for coord in sst.coords()]
    print coord_names
    if 'day_of_year' not in coord_names:
        icc.add_day_of_year(sst, 'time', name='day_of_year')

    ndays = sst.shape[0]
    day_of_year = sst.coord('day_of_year').points
    print 'in fix_sst ', day_of_year

    for day in range(ndays):
        day_number = day_of_year[day] - 1
        print('process day, month ', day, im)
        for ib, bin in enumerate(BIN['SICE']['XBINS'][:-1]):
            if bin < ice_min_change_nh - 1:
                continue
            ice_range = np.where(
                (np.abs(ice.data[day, :, :] - bin) < BIN['SICE']['SIZE'])
                & (ice.data[day, :, :] > ice_min_change_nh)
                & (ice.data.mask[day, :, :] == False))
            nhemi = np.where(ice_range[0] > lat_size / 2)
            print 'nhemi ', nhemi, ib, bin
            sst.data[day, ice_range[0][nhemi],
                     ice_range[1][nhemi]] = mean_freq_sice[ib, 0, day_number]

            ice_range_sh = np.where(
                (np.abs(ice.data[day, :, :] - bin) < BIN['SICE']['SIZE'])
                & (ice.data[day, :, :] > ice_min_change_sh)
                & (ice.data.mask[day, :, :] == False))
            shemi = np.where(ice_range_sh[0] < lat_size / 2)
            print 'shemi ', shemi, ib, bin
            sst.data[day, ice_range_sh[0][shemi],
                     ice_range_sh[1][shemi]] = mean_freq_sice[ib, 1,
                                                              day_number]
    return sst
Пример #11
0
    def test_basic(self):
        cube = self.cube
        time_coord = self.time_coord

        ccat.add_year(cube, time_coord, 'my_year')
        ccat.add_day_of_month(cube, time_coord, 'my_day_of_month')
        ccat.add_day_of_year(cube, time_coord, 'my_day_of_year')

        ccat.add_month(cube, time_coord, 'my_month')
        with warnings.catch_warnings(record=True):
            ccat.add_month_shortname(cube, time_coord, 'my_month_shortname')
        ccat.add_month_fullname(cube, time_coord, 'my_month_fullname')
        ccat.add_month_number(cube, time_coord, 'my_month_number')

        ccat.add_weekday(cube, time_coord, 'my_weekday')
        ccat.add_weekday_number(cube, time_coord, 'my_weekday_number')
        with warnings.catch_warnings(record=True):
            ccat.add_weekday_shortname(cube, time_coord,
                                       'my_weekday_shortname')
        ccat.add_weekday_fullname(cube, time_coord, 'my_weekday_fullname')

        ccat.add_season(cube, time_coord, 'my_season')
        ccat.add_season_number(cube, time_coord, 'my_season_number')
        with warnings.catch_warnings(record=True):
            ccat.add_season_month_initials(cube, time_coord,
                                           'my_season_month_initials')
        ccat.add_season_year(cube, time_coord, 'my_season_year')

        # also test 'generic' categorisation interface
        def _month_in_quarter(coord, pt_value):
            date = coord.units.num2date(pt_value)
            return (date.month - 1) % 3

        ccat.add_categorised_coord(cube, 'my_month_in_quarter', time_coord,
                                   _month_in_quarter)

        # To ensure consistent results between 32-bit and 64-bit
        # platforms, ensure all the numeric categorisation coordinates
        # are always stored as int64.
        for coord in cube.coords():
            if coord.long_name is not None and coord.points.dtype.kind == 'i':
                coord.points = coord.points.astype(np.int64)

        # check values
        self.assertCML(cube, ('categorisation', 'quickcheck.cml'))
def add_time_names(cube, year=False, month_number=False, day_of_year=False):
    '''
    Add additional coordiate names to time dimension
    '''
    if year:
        icc.add_year(cube, 'time', name='year')

    if month_number:
        try:
            icc.add_month_number(cube, 'time', name='month')
        except:
            pass

    if day_of_year:
        try:
            icc.add_day_of_year(cube, 'time', name='day_of_year')
        except:
            pass
Пример #13
0
    def vortex_clim(self):
        coord_cat.add_day_of_year(self.U_day, self.tname, name='day_number')

        ## quick find nearest latitude to 60 function
        def find_nearest(array, value):
            array = np.asarray(array)
            idx = (np.abs(array - value)).argmin()
            return array[idx]

        lat = find_nearest(self.U_day.coord('latitude').points, 60)
        U_vortex = self.U_day.extract(iris.Constraint(latitude=lat))
        plt.plot(np.arange(365), U_vortex[0:365].data)
        plt.show()
        self.vortex_clim = U_vortex.aggregated_by('day_number',
                                                  iris.analysis.MEAN)
        self.vortex_climSTD = U_vortex.aggregated_by('day_number',
                                                     iris.analysis.STD_DEV)

        return
def hourly2daily(hourly_cube):
    '''
    Aggregates the hourly precipitation cube into daily_cube
    :param iris.cube: hourly cube to be aggregated in daily
    '''
    # raise exception is not only one year in a cube?
    icat.add_day_of_year(hourly_cube,  'time')
    hourly_cube.coord('time').bounds = None
    #print(hourly_cube.coord('day_of_year'))
    print(hourly_cube.coord('day_of_year').points[-80:])
    print(hourly_cube.coord('day_of_year').points[:80])
    #print(hourly_cube.coord('day_of_year').bounds)
    if hourly_cube.units in ['kg/m2/s', 'kg m-2 s-1', 'mm day-1', 'mm/day']:
        daily_data = hourly_cube.aggregated_by('day_of_year', iana.MEAN)
    elif hourly_cube.units in ['mm', 'mm/h', 'mm h-1', 'mm/3hr', 'mm hour-1']:
        print('summing hourly')
        daily_data = hourly_cube.aggregated_by('day_of_year', iana.SUM)
        daily_data.units = cf_units.as_unit('mm day-1')
    else:
        raise ValueError('wrong units: {}'.format(hourly_cube.units))
    # daily_data.name = 'precipitation_rate'
    return daily_data
Пример #15
0
    def test_basic(self):
        cube = self.cube
        time_coord = self.time_coord

        ccat.add_year(cube, time_coord, "my_year")
        ccat.add_day_of_month(cube, time_coord, "my_day_of_month")
        ccat.add_day_of_year(cube, time_coord, "my_day_of_year")

        ccat.add_month(cube, time_coord, "my_month")
        ccat.add_month_fullname(cube, time_coord, "my_month_fullname")
        ccat.add_month_number(cube, time_coord, "my_month_number")

        ccat.add_weekday(cube, time_coord, "my_weekday")
        ccat.add_weekday_number(cube, time_coord, "my_weekday_number")
        ccat.add_weekday_fullname(cube, time_coord, "my_weekday_fullname")

        ccat.add_season(cube, time_coord, "my_season")
        ccat.add_season_number(cube, time_coord, "my_season_number")
        ccat.add_season_year(cube, time_coord, "my_season_year")

        # also test 'generic' categorisation interface
        def _month_in_quarter(coord, pt_value):
            date = coord.units.num2date(pt_value)
            return (date.month - 1) % 3

        ccat.add_categorised_coord(
            cube, "my_month_in_quarter", time_coord, _month_in_quarter
        )

        # To ensure consistent results between 32-bit and 64-bit
        # platforms, ensure all the numeric categorisation coordinates
        # are always stored as int64.
        for coord in cube.coords():
            if coord.long_name is not None and coord.points.dtype.kind == "i":
                coord.points = coord.points.astype(np.int64)

        # check values
        self.assertCML(cube, ("categorisation", "quickcheck.cml"))
Пример #16
0
    uwnd10m = uwnd10m.concatenate_cube()
    vwnd10m = vwnd10m.concatenate_cube()
    max_wndgust10m = max_wndgust10m.concatenate_cube()

    # Regrid U onto V
    print('Regridding U onto V (so they align in space)...')
    interpolator = iris.analysis.Linear()
    vwnd10m = vwnd10m.regrid(uwnd10m, interpolator)

    # Create a cube of wind speed
    print('Calculating wind speed...')
    windspeed = (uwnd10m**2 + vwnd10m**2)**0.5
    windspeed.rename('windspeed')

    # Create extra coordinate for daily statistics
    ct.add_day_of_year(windspeed, 'time')
    ct.add_day_of_year(max_wndgust10m, 'time')

    print('Calculating max wind speed...')
    max_speed = windspeed.aggregated_by(['day_of_year'], iris.analysis.MAX)

    print('Calculating max (max) gust...')
    max_gust = max_wndgust10m.aggregated_by(['day_of_year'], iris.analysis.MAX)

    # Event maximum
    print('Calculating event maxima...')
    event_max_speed = max_speed.collapsed('time', iris.analysis.MAX)
    event_max_gust = max_gust.collapsed('time', iris.analysis.MAX)

    # Save the calculation
    print('Saving calculations...')
Пример #17
0
    hadisst2_dir = '/home/users/mjrobert/hrcm/cache/malcolm/HadISST2/1x1/'
    cmip_1x1 = os.path.join(hadisst2_dir, 'cmip5_trend_1x1.nc')

    if not os.path.exists(cmip_1x1):
        trend_025 = iris.load_cube(cmip_file)
        trend_025.coord('longitude').circular = True
        c_ref = iris.load(datafile)[0]
        for coord in ['latitude','longitude']:
            c_ref.coord(coord).guess_bounds()
            trend_025.coord(coord).guess_bounds()
        trend_1x1 = trend_025.regrid(c_ref, iris.analysis.AreaWeighted())
        iris.save(trend_1x1, cmip_1x1)

    trend = iris.load_cube(cmip_1x1)
    icc.add_day_of_year(trend, 'time')
    icc.add_year(trend, 'time')

    hadisst2_files = glob.glob(os.path.join(hadisst2_dir, 'HadISST2_1x1_regrid_sst*'))
    

    '''
    for each year, read in the HadISST2 daily data
    read in the monthly data, dec year-1 to jan year +1
    do time interpolation from one time to the other
    '''
    hadisst_data = iris.load_cube(os.path.join(hadisst2_dir, 'HadISST2_1x1_regrid_sst_2002.nc'))
    icc.add_day_of_year(hadisst_data, 'time')
    YEARS = iris.Constraint(coord_values = {'year' : lambda l : l == 2002})
    sub_trend = trend.extract(YEARS)
    print  sub_trend
Пример #18
0
plot_SEB_composites()

# Find daily means, maxes, climatologies and anomalies
Ts_clim = iris.load_cube(
    '/gws/nopw/j04/bas_climate/users/ellgil82/hindcast/output/alloutput/Ts_climatology.nc'
)
Ts_clim.convert_units('celsius')
Ts_clim = np.concatenate((Ts_clim[244:].data, Ts_clim[:90].data), axis=0)
Tair_clim = iris.load_cube(
    '/gws/nopw/j04/bas_climate/users/ellgil82/hindcast/output/alloutput/Tair_1p5m_climatology.nc'
)
Tair_clim.convert_units('celsius')
Tair_clim = np.concatenate((Tair_clim[244:].data, Tair_clim[:90].data), axis=0)
import iris.coord_categorisation as cat

cat.add_day_of_year(var_dict['Ts'], 't', name='day')
cat.add_day_of_year(var_dict['Tair'], 't', name='day')
Ts_daymax = var_dict['Ts'].aggregated_by('day', iris.analysis.MAX)
Ts_daily = var_dict['Ts'].aggregated_by('day', iris.analysis.MEAN)
Ts_anom = Ts_daily - Ts_clim[:, 0, :, :]
Tair_daymax = var_dict['Tair'].aggregated_by('day', iris.analysis.MAX)
Tair_daily = var_dict['Tair'].aggregated_by('day', iris.analysis.MEAN)
Tair_anom = Tair_daily - Tair_clim[:, 0, :, :]


def plot_synop_composite(cf_var, c_var, u_var, v_var):
    fig = plt.figure(frameon=False, figsize=(
        9,
        10))  # !!change figure dimensions when you have a larger model domain
    fig.patch.set_visible(False)
    ax = fig.add_subplot(111)  #, projection=ccrs.PlateCarree())
Пример #19
0
def add_time_coord_cats(cube):
    """
    This function takes in an iris cube, and adds a range of
    numeric co-ordinate categorisations to it. Depending
    on the data, not all of the coords added will be relevant.

    args
    ----
    cube: iris cube that has a coordinate called 'time'

    Returns
    -------
    Cube: cube that has new time categorisation coords added

    Notes
    -----
    test

    A simple example:

    >>> file = os.path.join(conf.DATA_DIR, 'mslp.daily.rcm.viet.nc')
    >>> cube = iris.load_cube(file)
    >>> coord_names = [coord.name() for coord in cube.coords()]
    >>> print((', '.join(coord_names)))
    time, grid_latitude, grid_longitude
    >>> ccube = add_time_coord_cats(cube)
    >>> coord_names = [coord.name() for coord in ccube.coords()]
    >>> print((', '.join(coord_names)))
    time, grid_latitude, grid_longitude, day_of_month, day_of_year, month, \
month_number, season, season_number, year
    >>> # print every 50th value of the added time cat coords
    ... for c in coord_names[3:]:
    ...     print(ccube.coord(c).long_name)
    ...     print(ccube.coord(c).points[::50])
    ...
    day_of_month
    [ 1 21 11  1 21 11  1 21]
    day_of_year
    [  1  51 101 151 201 251 301 351]
    month
    ['Jan' 'Feb' 'Apr' 'Jun' 'Jul' 'Sep' 'Nov' 'Dec']
    month_number
    [ 1  2  4  6  7  9 11 12]
    season
    ['djf' 'djf' 'mam' 'jja' 'jja' 'son' 'son' 'djf']
    season_number
    [0 0 1 2 2 3 3 0]
    year
    [2000 2000 2000 2000 2000 2000 2000 2000]

    """

    # most errors pop up when you try to add a coord that has
    # previously been added, or the cube doesn't contain the
    # necessary attribute.

    ccube = cube.copy()

    # numeric
    try:
        iccat.add_day_of_year(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    try:
        iccat.add_day_of_month(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    try:
        iccat.add_month_number(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    try:
        iccat.add_season_number(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    try:
        iccat.add_year(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    # strings
    try:
        iccat.add_month(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    try:
        iccat.add_season(ccube, "time")
    except AttributeError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))
    except ValueError as err:
        print(("add_time_coord_cats: {}, skipping . . . ".format(err)))

    return ccube
def generate_future_siconc_from_sst(mean_freq_days, year, months, ice_mask,
                                    ice_mask_min, ice_ref):
    '''
    Use the maximum ice extent, the SST and the pdf relationship between SST and sea-ice to generate a future sea ice concentration
    '''
    #dir_in = '/group_workspaces/jasmin2/primavera1/WP6/forcing/HadISST2_submit/v1.2/'
    if year >= 2016:
        #future_sst_file = os.path.join(DATADIR, 'future', 'full_sst_1950_2100_025_daily_fixed.nc')
        future_sst_file = os.path.join(
            savedir, 'sst', 'future_sst_' + str(year) + '_025_daily_v1.nc')
    else:
        if len(months) == 12:
            future_sst_file = os.path.join(
                DATADIR, 'hadisst2_tos_daily_' + str(year) +
                '_fixed_day_v1_monthly_under_ice.nc')
        elif len(months) == 1:
            future_sst_file = os.path.join(
                DATADIR, 'hadisst2_tos_daily_' + str(year) + '_fixed_' +
                str(months[0] + 1).zfill(2) + '.nc')
        else:
            raise Exception('Must be either 12 months or 1 ' +
                            str(len(months)))

    future_siconc_file = os.path.join(savedir_ice, 'siconc',
                                      'future_siconc_{}_025_daily_v1.nc')
    print 'read sst ', future_sst_file
    full_sst = iris.load_cube(future_sst_file)

    try:
        #icc.add_month_number(full_siconc, 'time', name = 'month')
        icc.add_month_number(full_sst, 'time', name='month')
    except:
        pass

    try:
        #icc.add_year(full_siconc, 'time', name = 'year')
        icc.add_year(full_sst, 'time', name='year')
    except:
        pass

    #print 'full cube ',full_siconc.coord('year')
    new_sice_year = iris.cube.CubeList()

    print 'YEAR ', year
    fout_year = future_siconc_file.format(str(year))
    new_sice_month = iris.cube.CubeList()
    year_con = iris.Constraint(coord_values={'year': lambda l: l == int(year)})
    sst_this_year = full_sst.extract(year_con)
    full_siconc = sst_this_year.copy()
    print 'cube year ', sst_this_year

    lat_shape = sst_this_year.shape[1]
    for im in months:
        if im > 0 and im < 11:
            mm1 = im - 1
            mp1 = im + 1
        elif im == 0:
            mm1 = 11
            mp1 = im + 1
        elif im == 11:
            mm1 = im - 1
            mp1 = 0

        month = im + 1
        month_con = iris.Constraint(
            coord_values={'month': lambda l: l == int(month)})
        sst_this_month = sst_this_year.extract(month_con)

        if im == 0:
            month_con_m1 = iris.Constraint(
                coord_values={'month': lambda l: l == 1})
        else:
            month_con_m1 = iris.Constraint(
                coord_values={'month': lambda l: l == int(month - 1)})
        sst_last_month = sst_this_year.extract(month_con_m1)

        if im == 11:
            month_con_p1 = iris.Constraint(
                coord_values={'month': lambda l: l == 11})
        else:
            month_con_p1 = iris.Constraint(
                coord_values={'month': lambda l: l == int(month + 1)})
        sst_next_month = sst_this_year.extract(month_con_p1)

        siconc_template = full_siconc.extract(month_con)
        coord_names = [coord.name() for coord in siconc_template.coords()]
        print coord_names
        if 'day_of_year' not in coord_names:
            icc.add_day_of_year(siconc_template, 'time', name='day_of_year')
        siconc_template.data[...] = 0.0

        ndays = sst_this_month.shape[0]
        day_of_year = siconc_template.coord('day_of_year').points

        for day in range(ndays):
            day_number = day_of_year[day] - 1
            print 'process ', day, month, year, day_number
            for ib, bin in enumerate(BIN['SST']['XBINS'][:-1]):
                sst_range = np.where((bin < sst_this_month.data[day, :, :]) & (
                    bin + 1 >= sst_this_month.data[day, :, :])
                                     & (ice_mask.data[im, :, :] == 1))
                nhemi = np.where(sst_range[0] > lat_shape / 2)
                shemi = np.where(sst_range[0] < lat_shape / 2)
                siconc_template.data[
                    day, sst_range[0][nhemi],
                    sst_range[1][nhemi]] = mean_freq_days[year][ib, 0,
                                                                day_number]
                siconc_template.data[
                    day, sst_range[0][shemi],
                    sst_range[1][shemi]] = mean_freq_days[year][ib, 1,
                                                                day_number]
            print 'completed ', day, month, year

        siconc_template.data.mask[:, sst_this_month[0].data.mask] = True
        siconc_template.data.mask[:, ice_ref.data.mask] = True
        new_sice_month.append(siconc_template)
    new_sice_cube = new_sice_month.concatenate_cube()
    add_metadata(new_sice_cube)
    print 'write to ', fout_year
    iris.save(new_sice_cube,
              fout_year,
              unlimited_dimensions=['time'],
              fill_value=1.0e20)

    return fout_year
    def test_basic(self):
        # make a series of 'day numbers' for the time, that slide across month
        # boundaries
        day_numbers = np.arange(0, 600, 27, dtype=np.int32)

        cube = iris.cube.Cube(
            day_numbers, long_name='test cube', units='metres')

        # use day numbers as data values also (don't actually use this for
        # anything)
        cube.data = day_numbers

        time_coord = iris.coords.DimCoord(
            day_numbers, standard_name='time',
            units=iris.unit.Unit('days since epoch', 'gregorian'))
        cube.add_dim_coord(time_coord, 0)

        # add test coordinates for examples wanted
        ccat.add_year(cube, time_coord)
        ccat.add_day_of_month(cube, 'time')    # NB test passing coord-name
                                               # instead of coord itself
        ccat.add_day_of_year(cube, 'time', name='day_of_year')

        ccat.add_month(cube, time_coord)
        ccat.add_month_shortname(cube, time_coord, name='month_short')
        ccat.add_month_fullname(cube, time_coord, name='month_full')
        ccat.add_month_number(cube, time_coord, name='month_number')

        ccat.add_weekday(cube, time_coord)
        ccat.add_weekday_number(cube, time_coord, name='weekday_number')
        ccat.add_weekday_shortname(cube, time_coord, name='weekday_short')
        ccat.add_weekday_fullname(cube, time_coord, name='weekday_full')

        ccat.add_season(cube, time_coord)
        ccat.add_season_number(cube, time_coord, name='season_number')
        ccat.add_season_month_initials(cube, time_coord, name='season_months')
        ccat.add_season_year(cube, time_coord, name='year_ofseason')

        # also test 'generic' categorisation interface
        def _month_in_quarter(coord, pt_value):
            date = coord.units.num2date(pt_value)
            return (date.month - 1) % 3

        ccat.add_categorised_coord(cube,
                                   'month_in_quarter',
                                   time_coord,
                                   _month_in_quarter)

        for coord_name in ['month_number',
                           'month_in_quarter',
                           'weekday_number',
                           'season_number',
                           'year_ofseason',
                           'year',
                           'day',
                           'day_of_year']:
            cube.coord(coord_name).points = \
                cube.coord(coord_name).points.astype(np.int64)

        # check values
        self.assertCML(cube, ('categorisation', 'quickcheck.cml'))
Пример #22
0
        elif unit.name[:3] == 'day':
            thirty_mins = 0.5 / 24
        else:
            raise ValueError(f"Don't know how to deal with: '{unit.name}'")

        print('Subtracting half an hour from time coord first')
        new_points = cube.coord('time').points - thirty_mins
        cube.coord('time').points = new_points

    iccat.add_year(cube, 'time')
    if freq == 'mon':
        iccat.add_month_number(cube, 'time')
        agg_by = ['month_number', 'year']
        remove_later = 'month_number'
    elif freq == 'day':
        iccat.add_day_of_year(cube, 'time')
        agg_by = ['day_of_year', 'year']
        remove_later = 'day_of_year'
    else:
        raise ValueError('Unrecognised frequency')

    # compute averages
    print(f'Computing {freq} average')
    means = cube.aggregated_by(agg_by, iris.analysis.MEAN)

    # remove no longer needed aux coords
    means.remove_coord(remove_later)
    means.remove_coord('year')

    # make sure standard names are being used
    if means.var_name == 'pr':
Пример #23
0
def adjust_bias(obs_hist,
                sim_hist,
                sim_fut,
                realize_cubes=False,
                anonymous_dimension_name=None,
                halfwin_upper_bound_climatology=0,
                n_processes=1,
                **kwargs):
    """
    Adjusts biases grid cell by grid cell.

    Parameters
    ----------
    obs_hist : iris cube
        Cube of observed climate data representing the historical or training
        time period.
    sim_hist : iris cube
        Cube of simulated climate data representing the historical or training
        time period.
    sim_fut : iris cube
        Cube of simulated climate data representing the future or application
        time period.
    realize_cubes : boolean, optional
        Realize data of obs_hist, sim_hist, and sim_fut before beginning the
        bias adjustment grid cell by grid cell.
    anonymous_dimension_name : str, optional
        Used to name the first anonymous dimension of obs_hist, sim_hist, and
        sim_fut.
    halfwin_upper_bound_climatology : int, optional
        Determines the length of running windows used in the calculations of
        climatologies of upper bounds that is used to rescale all values of
        obs_hist, sim_hist, and sim_fut to values <= 1 before bias adjustment.
        The window length is set to halfwin_upper_bound_climatology * 2 + 1
        time steps. If halfwin_upper_bound_climatology == 0 then no rescaling
        is done.
    n_processes : int, optional
        Number of processes used for parallel processing.

    Returns
    -------
    sim_fut_ba : iris cube
        Result of bias adjustment.

    Other Parameters
    ----------------
    **kwargs : Passed on to adjust_bias_one_location.

    """
    # put iris cubes into dictionary
    cubes = {'obs_hist': obs_hist, 'sim_hist': sim_hist, 'sim_fut': sim_fut}

    space_shape = None
    for key, cube in cubes.items():
        # get cube shape beyond time axis
        if space_shape is None: space_shape = cube.shape[1:]
        else:
            assert space_shape == cube.shape[1:], 'cube shapes not compatible'
        # load iris cube data into memory
        if realize_cubes: d = cube.data
        # make sure the proleptic gregorian calendar is used in all input files
        uf.assert_calendar(cube, 'proleptic_gregorian')
        # make sure that time is the leading coordinate
        uf.assert_coord_axis(cube, 'time', 0)
        # name the first anonymous dimension
        uf.name_first_anonymous_dimension(cube, anonymous_dimension_name)
        # prepare scaling by upper bound climatology
        if halfwin_upper_bound_climatology: icc.add_day_of_year(cube, 'time')
        # prepare bias adjustment calendar month by calendar month
        icc.add_month_number(cube, 'time')
        # prepare detrending and cube concatenation
        icc.add_year(cube, 'time')

    # adjust every location individually using multiprocessing
    print('adjusting at location ...')
    abol = partial(
        adjust_bias_one_location,
        halfwin_upper_bound_climatology=halfwin_upper_bound_climatology,
        **kwargs)
    pool = mp.Pool(n_processes, maxtasksperchild=1000)
    time_series_adjusted = pool.imap(
        abol,
        zip(obs_hist.slices('time'), sim_hist.slices('time'),
            sim_fut.slices('time')))
    pool.close()

    # replace time series in sim_fut by the adjusted time series
    sim_fut_ba = sim_fut
    d = sim_fut_ba.data
    for i_location, tsa in zip(np.ndindex(space_shape), time_series_adjusted):
        d[(slice(None, None), ) + i_location] = tsa
        print(i_location)

    # remove auxiliary coordinates
    sim_fut_ba.remove_coord('year')
    sim_fut_ba.remove_coord('month_number')
    if halfwin_upper_bound_climatology: sim_fut_ba.remove_coord('day_of_year')

    return sim_fut_ba