def test_values(self): """Check adjusted temperature values are as expected""" result = apply_gridded_lapse_rate(self.temperature, self.lapse_rate, self.source_orog, self.dest_orog) # test that temperatures are reduced where destination orography # is higher than source source_lt_dest = np.where(self.source_orog.data < self.dest_orog.data) self.assertTrue( np.all(result.data[source_lt_dest] < self.temperature.data[source_lt_dest])) # test that temperatures are increased where destination orography # is lower than source source_gt_dest = np.where(self.source_orog.data > self.dest_orog.data) self.assertTrue( np.all(result.data[source_gt_dest] > self.temperature.data[source_gt_dest])) # test that temperatures are equal where destination orography # is equal to source source_eq_dest = np.where( np.isclose(self.source_orog.data, self.dest_orog.data)) self.assertArrayAlmostEqual(result.data[source_eq_dest], self.temperature.data[source_eq_dest]) # match specific values self.assertArrayAlmostEqual(result.data, self.expected_data)
def test_basic(self): """Test output is cube with correct name, type and units""" result = apply_gridded_lapse_rate(self.temperature, self.lapse_rate, self.source_orog, self.dest_orog) self.assertIsInstance(result, iris.cube.Cube) self.assertEqual(result.name(), 'screen_temperature') self.assertEqual(result.units, 'K') self.assertEqual(result.dtype, np.float32)
def test_missing_coord(self): """Test error if temperature cube has realizations but lapse rate does not""" temp_3d = add_coordinate(self.temperature, [0, 1, 2], 'realization') msg = 'Lapse rate cube has no coordinate "realization"' with self.assertRaisesRegex(ValueError, msg): _ = apply_gridded_lapse_rate(temp_3d, self.lapse_rate, self.source_orog, self.dest_orog)
def test_spatial_mismatch(self): """Test error if source orography grid is not matched to temperature""" new_y_points = self.source_orog.coord(axis='y').points + 100. self.source_orog.coord(axis='y').points = new_y_points msg = 'Source orography spatial coordinates do not match' with self.assertRaisesRegex(ValueError, msg): _ = apply_gridded_lapse_rate(self.temperature, self.lapse_rate, self.source_orog, self.dest_orog)
def test_unmatched_realizations(self): """Test error if realizations on temperature and lapse rate do not match""" temp_3d = add_coordinate(self.temperature, [0, 1, 2], 'realization') lrt_3d = add_coordinate(self.lapse_rate, [2, 3, 4], 'realization') msg = 'Lapse rate cube coordinate "realization" does not match ' with self.assertRaisesRegex(ValueError, msg): _ = apply_gridded_lapse_rate(temp_3d, lrt_3d, self.source_orog, self.dest_orog)
def test_unit_adjustment(self): """Test correct values are retrieved if input cubes have incorrect units""" self.temperature.convert_units('degC') self.source_orog.convert_units('km') result = apply_gridded_lapse_rate(self.temperature, self.lapse_rate, self.source_orog, self.dest_orog) self.assertEqual(result.units, 'K') self.assertArrayAlmostEqual(result.data, self.expected_data)
def test_realizations(self): """Test processing of a cube with multiple realizations""" temp_3d = add_coordinate(self.temperature, [0, 1, 2], 'realization') lrt_3d = add_coordinate(self.lapse_rate, [0, 1, 2], 'realization') result = apply_gridded_lapse_rate(temp_3d, lrt_3d, self.source_orog, self.dest_orog) self.assertArrayEqual( result.coord('realization').points, np.array([0, 1, 2])) for subcube in result.slices_over('realization'): self.assertArrayAlmostEqual(subcube.data, self.expected_data)
def process(temperature, lapse_rate, source_orog, target_orog): """ Apply downscaling temperature adjustment using calculated lapse rate. Args: temperature (iris.cube.Cube): Input temperature Cube. lapse_rate (iris.cube.Cube): Lapse rate Cube. source_orog (iris.cube.Cube): Source model orography. target_orog (iris.cube.Cube): Target orography to which temperature will be downscaled. Returns: result (iris.cube.Cube): Cube after lapse rate has been applied to temperature data. """ # apply lapse rate to temperature data result = apply_gridded_lapse_rate(temperature, lapse_rate, source_orog, target_orog) return result
def main(argv=None): """Apply lapse rates to temperature data.""" parser = ArgParser(description='Apply downscaling temperature adjustment ' 'using calculated lapse rate.') parser.add_argument('temperature_filepath', metavar='TEMPERATURE_FILEPATH', help='Full path to input temperature NetCDF file') parser.add_argument('lapse_rate_filepath', metavar='LAPSE_RATE_FILEPATH', help='Full path to input lapse rate NetCDF file') parser.add_argument('source_orography', metavar='SOURCE_OROG_FILE', help='Full path to NetCDF file containing the source ' 'model orography') parser.add_argument('target_orography', metavar='TARGET_OROG_FILE', help='Full path to target orography NetCDF file ' '(to which temperature will be downscaled)') parser.add_argument('output_file', metavar='OUTPUT_FILE', help='File name ' 'to write lapse rate adjusted temperature data') args = parser.parse_args(args=argv) # read cubes temperature = load_cube(args.temperature_filepath) lapse_rate = load_cube(args.lapse_rate_filepath) source_orog = load_cube(args.source_orography) target_orog = load_cube(args.target_orography) # apply lapse rate to temperature data adjusted_temperature = apply_gridded_lapse_rate(temperature, lapse_rate, source_orog, target_orog) # save to output file save_netcdf(adjusted_temperature, args.output_file)
def process(temperature: cli.inputcube, lapse_rate: cli.inputcube, source_orography: cli.inputcube, target_orography: cli.inputcube): """Apply downscaling temperature adjustment using calculated lapse rate. Args: temperature (iris.cube.Cube): Input temperature cube. lapse_rate (iris.cube.Cube): Lapse rate cube. source_orography (iris.cube.Cube): Source model orography. target_orography (iris.cube.Cube): Target orography to which temperature will be downscaled. Returns: iris.cube.Cube: Temperature cube after lapse rate adjustment has been applied. """ from improver.lapse_rate import apply_gridded_lapse_rate # apply lapse rate to temperature data result = apply_gridded_lapse_rate(temperature, lapse_rate, source_orography, target_orography) return result