示例#1
0
    def _add_available_aux_coords(self, cube, filenames):
        from iris.aux_factory import HybridPressureFactory
        from iris.coords import AuxCoord
        from iris.exceptions import CoordinateNotFoundError
        import iris

        if cube.coords('hybrid A coefficient at layer midpoints'):

            # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa
            cube.coord('hybrid A coefficient at layer midpoints').convert_units('hPa')

            try:
                surface_pressure = cube.coord('surface pressure')
            except iris.exceptions.CoordinateNotFoundError as e:
                # If there isn't a surface pressure coordinate we can try and pull out the lowest pressure level
                with demote_warnings():
                    surface_pressure_cubes = iris.load(filenames, 'atmospheric pressure at interfaces',
                                                       callback=self.load_multiple_files_callback)
                surface_pressure_cube = surface_pressure_cubes.concatenate_cube()[:, -1, :, :]
                surface_pressure = AuxCoord(points=surface_pressure_cube.data, long_name='surface pressure', units='Pa')
                cube.add_aux_coord(surface_pressure, (0, 2, 3))
 
            surface_pressure.convert_units('hPa')
 
            if len(cube.coords(long_name='hybrid level at layer midpoints')) > 0:
                cube.add_aux_factory(HybridPressureFactory(delta=cube.coord('hybrid A coefficient at layer midpoints'),
                                                           sigma=cube.coord('hybrid B coefficient at layer midpoints'),
                                                          surface_air_pressure=surface_pressure))
示例#2
0
 def test_preserves_lazy(self):
     test_bounds = np.array([[[11.0, 12.0], [12.0, 13.0], [13.0, 14.0]],
                             [[21.0, 22.0], [22.0, 23.0], [23.0, 24.0]]])
     test_points = np.array([[11.1, 12.2, 13.3], [21.4, 22.5, 23.6]])
     lazy_points = as_lazy_data(test_points)
     lazy_bounds = as_lazy_data(test_bounds)
     coord = AuxCoord(points=lazy_points, bounds=lazy_bounds, units='m')
     coord.convert_units('ft')
     self.assertTrue(coord.has_lazy_points())
     self.assertTrue(coord.has_lazy_bounds())
     test_points_ft = Unit('m').convert(test_points, 'ft')
     test_bounds_ft = Unit('m').convert(test_bounds, 'ft')
     self.assertArrayAllClose(coord.points, test_points_ft)
     self.assertArrayAllClose(coord.bounds, test_bounds_ft)
示例#3
0
    def _add_available_aux_coords(self, cube, filenames):
        import iris
        from iris.aux_factory import HybridPressureFactory
        from iris.coords import AuxCoord
        from iris.exceptions import CoordinateNotFoundError

        # Only do this for fields with a vertical component - this check is a bit hacky though (doesn't consider 3D with no time...)
        if cube.ndim == 4:
            # Only read the first file for these coefficients as they are time-independant and iris won't merge them
            hybrid_a = _get_cubes(filenames, 'hybrid A coefficient at layer midpoints')
            hybrid_b = _get_cubes(filenames, 'hybrid B coefficient at layer midpoints')

            hybrid_a_coord = AuxCoord(points=hybrid_a[0].data, long_name='hybrid A coefficient at layer midpoints', units='Pa')
            hybrid_b_coord = AuxCoord(points=hybrid_b[0].data, long_name='hybrid B coefficient at layer midpoints', units='1')

            if cube.coords('surface pressure'):
                surface_pressure = cube.coord('surface pressure')
            else:
                try:
                    # If there isn't a surface pressure coordinate we can try and pull out the lowest pressure level
                    surface_pressure_cubes = _get_cubes(filenames, 'atmospheric pressure at interfaces',
                                                        callback=self.load_multiple_files_callback)
                    surface_pressure_cube = surface_pressure_cubes.concatenate_cube()[:,-1,:,:]
                    surface_pressure = AuxCoord(points=surface_pressure_cube.data, long_name='surface pressure', units='Pa')
                    cube.add_aux_coord(surface_pressure, (0, 2, 3))
                except ValueError:
                    # Try and get it from the vphysc stream
                    v_files = ['_'.join(f.split('_')[:-1]) + '_vphysc.nc' for f in filenames]
                    try:
                        surface_pressure_cubes = _get_cubes(v_files, 'atmospheric pressure at interfaces',
                                                            callback=self.load_multiple_files_callback)
                    except:
                        # If we can't do that then just exit - there must be a cleaner way to do this...
                        return
                    surface_pressure_cube = surface_pressure_cubes.concatenate_cube()[:,-1,:,:]
                    surface_pressure = AuxCoord(points=surface_pressure_cube.data, long_name='surface pressure', units='Pa')
                    cube.add_aux_coord(surface_pressure, (0, 2, 3))

            # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa
            hybrid_a_coord.convert_units('hPa')
            surface_pressure.convert_units('hPa')

            cube.add_aux_coord(hybrid_a_coord, (1,))
            cube.add_aux_coord(hybrid_b_coord, (1,))

            if len(cube.coords(long_name='hybrid level at layer midpoints')) > 0:
                cube.add_aux_factory(HybridPressureFactory(delta=hybrid_a_coord, sigma=hybrid_b_coord,
                                                           surface_air_pressure=surface_pressure))
示例#4
0
    def _add_available_aux_coords(self, cube, filenames):
        from iris.aux_factory import HybridPressureFactory
        from iris.coords import AuxCoord
        from cis.data_io.netcdf import read

        ps_filenames = [
            f.replace('concbc', 'ps_TL95L80_192x48NH_3hr') for f in filenames
        ]

        # These will be the same for all files
        hybrid_a = read(ps_filenames[0], 'a')['a']
        hybrid_b = read(ps_filenames[0], 'b')['b']

        hybrid_a_coord = AuxCoord(
            points=hybrid_a[:],
            long_name='vertical coordinate formula term: a(k)',
            units='Pa')
        hybrid_b_coord = AuxCoord(
            points=hybrid_b[:],
            long_name='vertical coordinate formula term: b(k)',
            units='1')

        # This needs to be from each file and then merged
        surface_pressure_cube = _get_cubes(
            ps_filenames, 'ps',
            callback=self.load_multiple_files_callback).concatenate_cube()
        surface_pressure = AuxCoord(points=surface_pressure_cube.data,
                                    standard_name='surface_air_pressure',
                                    long_name='surface pressure',
                                    units='Pa')
        # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa
        hybrid_a_coord.convert_units('hPa')
        surface_pressure.convert_units('hPa')

        cube.add_aux_coord(surface_pressure, (0, 2, 3))

        cube.add_aux_coord(hybrid_a_coord, (1, ))
        cube.add_aux_coord(hybrid_b_coord, (1, ))

        cube.add_aux_factory(
            HybridPressureFactory(delta=hybrid_a_coord,
                                  sigma=hybrid_b_coord,
                                  surface_air_pressure=surface_pressure))
示例#5
0
    def _add_available_aux_coords(self, cube, filenames):
        import iris
        from iris.aux_factory import HybridPressureFactory
        from iris.coords import AuxCoord
        from iris.exceptions import CoordinateNotFoundError

        # Only do this for fields with a vertical component - this check is a bit hacky though (doesn't consider 3D with no time...)
        if cube.ndim == 4:
            # Only read the first file for these coefficients as they are time-independant and iris won't merge them
            hybrid_a = _get_cubes(filenames,
                                  'hybrid A coefficient at layer midpoints')
            hybrid_b = _get_cubes(filenames,
                                  'hybrid B coefficient at layer midpoints')

            hybrid_a_coord = AuxCoord(
                points=hybrid_a[0].data,
                long_name='hybrid A coefficient at layer midpoints',
                units='Pa',
                var_name='hyam')
            hybrid_b_coord = AuxCoord(
                points=hybrid_b[0].data,
                long_name='hybrid B coefficient at layer midpoints',
                units='1',
                var_name='hybm')

            if cube.coords('surface pressure'):
                surface_pressure = cube.coord('surface pressure')
            elif cube.coords('surface_air_pressure'):
                surface_pressure = cube.coord('surface_air_pressure')
            else:
                try:
                    # If there isn't a surface pressure coordinate we can try loading it manually
                    surface_pressure_cube = _get_cubes(
                        filenames,
                        'surface_air_pressure',
                        callback=self.load_multiple_files_callback
                    ).concatenate_cube()
                    surface_pressure = AuxCoord(
                        points=surface_pressure_cube.data,
                        standard_name='surface_air_pressure',
                        long_name='surface pressure',
                        units='Pa')
                    cube.add_aux_coord(surface_pressure, (0, 2, 3))
                except ValueError:
                    try:
                        # If there isn't a surface pressure coordinate we can try and pull out the lowest pressure level
                        surface_pressure_cubes = _get_cubes(
                            filenames,
                            'atmospheric pressure at interfaces',
                            callback=self.load_multiple_files_callback)
                        surface_pressure_cube = surface_pressure_cubes.concatenate_cube(
                        )[:, -1, :, :]
                        surface_pressure = AuxCoord(
                            points=surface_pressure_cube.data,
                            long_name='surface pressure',
                            units='Pa')
                        cube.add_aux_coord(surface_pressure, (0, 2, 3))
                    except ValueError:
                        # Try and get it from the vphysc stream
                        v_files = [
                            '_'.join(f.split('_')[:-1]) + '_vphyscm.nc'
                            for f in filenames
                        ]
                        try:
                            surface_pressure_cubes = _get_cubes(
                                v_files,
                                'atmospheric pressure at interfaces',
                                callback=self.load_multiple_files_callback)
                        except:
                            # If we can't do that then just exit - there must be a cleaner way to do this...
                            return
                        surface_pressure_cube = surface_pressure_cubes.concatenate_cube(
                        )[:, -1, :, :]
                        surface_pressure = AuxCoord(
                            points=surface_pressure_cube.data,
                            long_name='surface pressure',
                            units='Pa')
                        cube.add_aux_coord(surface_pressure, (0, 2, 3))

            # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa
            hybrid_a_coord.convert_units('hPa')
            surface_pressure.convert_units('hPa')

            cube.add_aux_coord(hybrid_a_coord, (1, ))
            cube.add_aux_coord(hybrid_b_coord, (1, ))

            if len(cube.coords(
                    long_name='hybrid level at layer midpoints')) > 0:
                cube.add_aux_factory(
                    HybridPressureFactory(
                        delta=hybrid_a_coord,
                        sigma=hybrid_b_coord,
                        surface_air_pressure=surface_pressure))
示例#6
0
    def create_data_object(self, filenames, variable):
        logging.debug("Creating data object for variable " + variable)

        variables = [("ER2_IMU/Longitude", "x"), ("ER2_IMU/Latitude", "y"),
                     ("ER2_IMU/gps_time", "t"), ("State/Pressure", "p"),
                     ("DataProducts/Altitude", "z"), ("header/date", ""),
                     (variable, '')]

        logging.info("Listing coordinates: " + str(variables))

        var_data = read_many_files_individually(filenames,
                                                [v[0] for v in variables])

        date_times = []
        for times, date in zip(var_data['ER2_IMU/gps_time'],
                               var_data['header/date']):
            # Date is stored as an array (of length 92??) of floats with format: yyyymmdd
            date_str = str(int(date[0]))
            t_unit = Unit('hours since {}-{}-{} 00:00:00'.format(
                date_str[0:4], date_str[4:6], date_str[6:8]))
            date_times.append(
                t_unit.convert(get_data(times), cis_standard_time_unit))

        # time_data = utils.concatenate([get_data(i) for i in var_data['ER2_IMU/gps_time']])
        # date_str = str(int(var_data['header/date'][0][0]))
        # Flatten the data by taking the 0th column of the transpose
        time_coord = DimCoord(utils.concatenate(date_times).T[0],
                              standard_name='time',
                              units=cis_standard_time_unit)

        # TODO This won't work for multiple files since the altitude bins are different for each flight...
        alt_data = utils.concatenate(
            [get_data(i) for i in var_data["DataProducts/Altitude"]])
        alt_coord = DimCoord(alt_data[0], standard_name='altitude', units='m')

        pres_data = utils.concatenate(
            [get_data(i) for i in var_data["State/Pressure"]])
        pres_coord = AuxCoord(pres_data,
                              standard_name='air_pressure',
                              units='atm')
        # Fix the air-pressure units
        pres_coord.convert_units('hPa')

        lat_data = utils.concatenate(
            [get_data(i) for i in var_data['ER2_IMU/Latitude']])
        lat_coord = AuxCoord(lat_data.T[0], standard_name='latitude')

        lon_data = utils.concatenate(
            [get_data(i) for i in var_data['ER2_IMU/Longitude']])
        lon_coord = AuxCoord(lon_data.T[0], standard_name='longitude')

        data = utils.concatenate([get_data(i) for i in var_data[variable]])
        metadata = get_metadata(var_data[variable][0])

        cube = Cube(np.ma.masked_invalid(data),
                    long_name=metadata.misc['Description'],
                    units=self.clean_units(metadata.units),
                    dim_coords_and_dims=[(alt_coord, 1), (time_coord, 0)],
                    aux_coords_and_dims=[(lat_coord, (0, )),
                                         (lon_coord, (0, )),
                                         (pres_coord, (0, 1))])
        gd = GriddedData.make_from_cube(cube)
        return gd