def test_basic_numbered_1_tile(self, use_save_dataset, caplog): """Test creating a single numbered tile.""" from satpy.writers.awips_tiled import AWIPSTiledWriter data = self._get_test_data() area_def = self._get_test_area() input_data_arr = self._get_test_lcc_data(data, area_def) with caplog.at_level(logging.DEBUG): w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) if use_save_dataset: w.save_dataset(input_data_arr, sector_id='TEST', source_name='TESTS') else: w.save_datasets([input_data_arr], sector_id='TEST', source_name='TESTS') assert "no routine matching" not in caplog.text assert "Can't format string" not in caplog.text all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert len(all_files) == 1 assert os.path.basename( all_files[0] ) == 'TESTS_AII_PLAT_SENSOR_test_ds_TEST_T001_20180101_1200.nc' for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) output_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, output_ds) scale_factor = output_ds['data'].encoding['scale_factor'] np.testing.assert_allclose(input_data_arr.values, output_ds['data'].data, atol=scale_factor / 2)
def test_basic_numbered_tiles_rgb(self, tmp_path): """Test creating a multiple numbered tiles with RGB.""" from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=str(tmp_path), compress=True) data = da.from_array(np.linspace(0., 1., 60000, dtype=np.float32).reshape( (3, 200, 100)), chunks=50) area_def = _get_test_area() ds = _get_test_lcc_data(data, area_def) ds = ds.rename( dict((old, new) for old, new in zip(ds.dims, ['bands', 'y', 'x']))) ds.coords['bands'] = ['R', 'G', 'B'] w.save_datasets([ds], sector_id='TEST', source_name="TESTS", tile_count=(3, 3)) chan_files = glob( os.path.join(str(tmp_path), 'TESTS_AII*test_ds_R*.nc')) all_files = chan_files[:] assert len(chan_files) == 9 chan_files = glob( os.path.join(str(tmp_path), 'TESTS_AII*test_ds_G*.nc')) all_files.extend(chan_files) assert len(chan_files) == 9 chan_files = glob( os.path.join(str(tmp_path), 'TESTS_AII*test_ds_B*.nc')) assert len(chan_files) == 9 all_files.extend(chan_files) for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) masked_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, masked_ds)
def test_basic_lettered_tiles_diff_projection(self): """Test creating a lettered grid from data with differing projection..""" import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) crs = CRS( "+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. +lat_0=45 +lat_1=45 +units=m +no_defs" ) data = self._get_test_data(shape=(2000, 1000), chunks=500) area_def = self._get_test_area(shape=(2000, 1000), crs=crs, extents=(-1000000., -1500000., 1000000., 1500000.)) ds = self._get_test_lcc_data(data, area_def) # tile_count should be ignored since we specified lettered_grid w.save_datasets([ds], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) all_files = sorted(glob(os.path.join(self.base_dir, 'TESTS_AII*.nc'))) assert len(all_files) == 24 assert "TC02" in all_files[0] # the first tile should be TC02 for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) masked_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, masked_ds) assert masked_ds.attrs[ 'start_date_time'] == self.start_time.strftime( '%Y-%m-%dT%H:%M:%S')
def test_basic_lettered_tiles(self): """Test creating a lettered grid.""" import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) data = self._get_test_data(shape=(2000, 1000), chunks=500) area_def = self._get_test_area(shape=(2000, 1000), extents=(-1000000., -1500000., 1000000., 1500000.)) ds = self._get_test_lcc_data(data, area_def) # tile_count should be ignored since we specified lettered_grid w.save_datasets([ds], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert len(all_files) == 16 for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) masked_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, masked_ds) assert masked_ds.attrs[ 'start_date_time'] == self.start_time.strftime( '%Y-%m-%dT%H:%M:%S')
def test_lettered_tiles_sector_ref(self): """Test creating a lettered grid using the sector as reference.""" import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) data = self._get_test_data(shape=(2000, 1000), chunks=500) area_def = self._get_test_area(shape=(2000, 1000), extents=(-1000000., -1500000., 1000000., 1500000.)) ds = self._get_test_lcc_data(data, area_def) w.save_datasets([ds], sector_id='LCC', source_name="TESTS", lettered_grid=True, use_sector_reference=True, use_end_time=True) all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert len(all_files) == 16 for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) masked_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, masked_ds) expected_start = ( self.start_time + timedelta(minutes=20)).strftime('%Y-%m-%dT%H:%M:%S') assert masked_ds.attrs['start_date_time'] == expected_start
def test_basic_numbered_tiles(self, tile_count, tile_size): """Test creating a multiple numbered tiles.""" import xarray as xr import dask from satpy.writers.awips_tiled import AWIPSTiledWriter from satpy.tests.utils import CustomScheduler input_data_arr = self._get_test_lcc_data() w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) save_kwargs = dict(sector_id='TEST', source_name="TESTS", tile_count=tile_count, tile_size=tile_size, extra_global_attrs={'my_global': 'TEST'}) should_error = tile_count is None and tile_size is None if should_error: with dask.config.set(scheduler=CustomScheduler(0)),\ pytest.raises(ValueError, match=r'Either.*tile_count.*'): w.save_datasets([input_data_arr], **save_kwargs) else: with dask.config.set(scheduler=CustomScheduler(1)): w.save_datasets([input_data_arr], **save_kwargs) all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) expected_num_files = 0 if should_error else 9 assert len(all_files) == expected_num_files for fn in all_files: ds = xr.open_dataset(fn, mask_and_scale=False) check_required_common_attributes(ds) assert ds.attrs['my_global'] == 'TEST' stime = input_data_arr.attrs['start_time'] assert ds.attrs['start_date_time'] == stime.strftime( '%Y-%m-%dT%H:%M:%S')
def test_basic_numbered_1_tile(self, use_save_dataset): """Test creating a single numbered tile.""" import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter input_data_arr = self._get_test_lcc_data() w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) if use_save_dataset: w.save_dataset(input_data_arr, sector_id='TEST', source_name='TESTS') else: w.save_datasets([input_data_arr], sector_id='TEST', source_name='TESTS') all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert len(all_files) == 1 assert os.path.basename( all_files[0] ) == 'TESTS_AII_PLAT_SENSOR_test_ds_TEST_T001_20180101_1200.nc' for fn in all_files: output_ds = xr.open_dataset(fn, mask_and_scale=False) check_required_common_attributes(output_ds) output_ds = xr.open_dataset(fn, mask_and_scale=True) scale_factor = output_ds['data'].encoding['scale_factor'] np.testing.assert_allclose(input_data_arr.values, output_ds['data'].data, atol=scale_factor / 2)
def test_lettered_tiles_bad_filename(self): """Test creating a lettered grid with a bad filename.""" from satpy.writers.awips_tiled import AWIPSTiledWriter from xarray import DataArray from pyresample.geometry import AreaDefinition w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True, filename="{Bad Key}.nc") area_def = AreaDefinition( 'test', 'test', 'test', ('+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. ' '+lat_0=25 +lat_1=25 +units=m +no_defs'), 1000, 2000, (-1000000., -1500000., 1000000., 1500000.), ) now = datetime(2018, 1, 1, 12, 0, 0) ds = DataArray( da.from_array(np.linspace(0., 1., 2000000, dtype=np.float32).reshape((2000, 1000)), chunks=500), attrs=dict( name='test_ds', platform_name='PLAT', sensor='SENSOR', units='1', area=area_def, start_time=now, end_time=now + timedelta(minutes=20)) ) with pytest.raises(KeyError): w.save_datasets([ds], sector_id='LCC', source_name='TESTS', tile_count=(3, 3), lettered_grid=True)
def test_lettered_tiles_no_valid_data(self): """Test creating a lettered grid with no valid data.""" from satpy.writers.awips_tiled import AWIPSTiledWriter from xarray import DataArray from pyresample.geometry import AreaDefinition from pyresample.utils import proj4_str_to_dict w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) area_def = AreaDefinition( 'test', 'test', 'test', proj4_str_to_dict('+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. ' '+lat_0=25 +lat_1=25 +units=m +no_defs'), 1000, 2000, (-1000000., -1500000., 1000000., 1500000.), ) now = datetime(2018, 1, 1, 12, 0, 0) ds = DataArray( da.full((2000, 1000), np.nan, chunks=500, dtype=np.float32), attrs=dict( name='test_ds', platform_name='PLAT', sensor='SENSOR', units='1', area=area_def, start_time=now, end_time=now + timedelta(minutes=20)) ) w.save_datasets([ds], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) # No files created - all NaNs should result in no tiles being created all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert not all_files
def test_multivar_numbered_tiles_glm(self, sector, extra_kwargs): """Test creating a tiles with multiple variables.""" import os import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter os.environ['ORGANIZATION'] = '1' * 50 w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) data = self._get_test_data() area_def = self._get_test_area() ds1 = self._get_test_lcc_data(data, area_def) ds1.attrs.update( dict(name='total_energy', platform_name='GOES-17', sensor='SENSOR', units='1', scan_mode='M3', scene_abbr=sector, platform_shortname="G17")) ds2 = ds1.copy() ds2.attrs.update({ 'name': 'flash_extent_density', }) ds3 = ds1.copy() ds3.attrs.update({ 'name': 'average_flash_area', }) dqf = ds1.copy() dqf = (dqf * 255).astype(np.uint8) dqf.attrs = ds1.attrs.copy() dqf.attrs.update({ 'name': 'DQF', '_FillValue': 1, }) w.save_datasets([ds1, ds2, ds3, dqf], sector_id='TEST', source_name="TESTS", tile_count=(3, 3), template='glm_l2_rad{}'.format(sector.lower()), **extra_kwargs) fn_glob = self._get_glm_glob_filename(extra_kwargs) all_files = glob(os.path.join(self.base_dir, fn_glob)) assert len(all_files) == 9 for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) masked_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, masked_ds) if sector == 'C': assert masked_ds.attrs[ 'time_coverage_end'] == self.end_time.strftime( '%Y-%m-%dT%H:%M:%S.%fZ') else: # 'F' assert masked_ds.attrs[ 'time_coverage_end'] == self.end_time.strftime( '%Y-%m-%dT%H:%M:%SZ')
def test_basic_numbered_tiles_rgb(self): """Test creating a multiple numbered tiles with RGB.""" from satpy.writers.awips_tiled import AWIPSTiledWriter import xarray as xr from xarray import DataArray from pyresample.geometry import AreaDefinition from pyresample.utils import proj4_str_to_dict w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) area_def = AreaDefinition( 'test', 'test', 'test', proj4_str_to_dict( '+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. ' '+lat_0=25 +lat_1=25 +units=m +no_defs'), 100, 200, (-1000., -1500., 1000., 1500.), ) now = datetime(2018, 1, 1, 12, 0, 0) ds = DataArray(da.from_array(np.linspace(0., 1., 60000, dtype=np.float32).reshape( (3, 200, 100)), chunks=50), dims=('bands', 'y', 'x'), coords={'bands': ['R', 'G', 'B']}, attrs=dict(name='test_ds', platform_name='PLAT', sensor='SENSOR', units='1', area=area_def, start_time=now, end_time=now + timedelta(minutes=20))) w.save_datasets([ds], sector_id='TEST', source_name="TESTS", tile_count=(3, 3)) chan_files = glob( os.path.join(self.base_dir, 'TESTS_AII*test_ds_R*.nc')) all_files = chan_files[:] assert len(chan_files) == 9 chan_files = glob( os.path.join(self.base_dir, 'TESTS_AII*test_ds_G*.nc')) all_files.extend(chan_files) assert len(chan_files) == 9 chan_files = glob( os.path.join(self.base_dir, 'TESTS_AII*test_ds_B*.nc')) assert len(chan_files) == 9 all_files.extend(chan_files) for fn in all_files: ds = xr.open_dataset(fn, mask_and_scale=False) check_required_common_attributes(ds)
def test_lettered_tiles_no_fit(self): """Test creating a lettered grid with no data overlapping the grid.""" from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) data = self._get_test_data(shape=(2000, 1000), chunks=500) area_def = self._get_test_area(shape=(2000, 1000), extents=(4000000., 5000000., 5000000., 6000000.)) ds = self._get_test_lcc_data(data, area_def) w.save_datasets([ds], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) # No files created all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert not all_files
def test_lettered_tiles_no_valid_data(self): """Test creating a lettered grid with no valid data.""" from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) data = da.full((2000, 1000), np.nan, chunks=500, dtype=np.float32) area_def = self._get_test_area(shape=(2000, 1000), extents=(-1000000., -1500000., 1000000., 1500000.)) ds = self._get_test_lcc_data(data, area_def) w.save_datasets([ds], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) # No files created - all NaNs should result in no tiles being created all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert not all_files
def test_lettered_tiles_bad_filename(self): """Test creating a lettered grid with a bad filename.""" from satpy.writers.awips_tiled import AWIPSTiledWriter w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True, filename="{Bad Key}.nc") data = self._get_test_data(shape=(2000, 1000), chunks=500) area_def = self._get_test_area(shape=(2000, 1000), extents=(-1000000., -1500000., 1000000., 1500000.)) ds = self._get_test_lcc_data(data, area_def) with pytest.raises(KeyError): w.save_datasets([ds], sector_id='LCC', source_name='TESTS', tile_count=(3, 3), lettered_grid=True)
def test_lettered_tiles_sector_ref(self): """Test creating a lettered grid using the sector as reference.""" import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter from xarray import DataArray from pyresample.geometry import AreaDefinition from pyresample.utils import proj4_str_to_dict w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) area_def = AreaDefinition( 'test', 'test', 'test', proj4_str_to_dict( '+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. ' '+lat_0=25 +lat_1=25 +units=m +no_defs'), 1000, 2000, (-1000000., -1500000., 1000000., 1500000.), ) now = datetime(2018, 1, 1, 12, 0, 0) ds = DataArray(da.from_array(np.linspace(0., 1., 2000000, dtype=np.float32).reshape( (2000, 1000)), chunks=500), attrs=dict(name='test_ds', platform_name='PLAT', sensor='SENSOR', units='1', area=area_def, start_time=now, end_time=now + timedelta(minutes=20))) w.save_datasets([ds], sector_id='LCC', source_name="TESTS", lettered_grid=True, use_sector_reference=True, use_end_time=True) all_files = glob(os.path.join(self.base_dir, 'TESTS_AII*.nc')) assert len(all_files) == 16 for fn in all_files: ds = xr.open_dataset(fn, mask_and_scale=False) check_required_common_attributes(ds) assert ds.attrs['start_date_time'] == ( now + timedelta(minutes=20)).strftime('%Y-%m-%dT%H:%M:%S')
def test_basic_numbered_tiles(self, tile_count, tile_size, tmp_path): """Test creating a multiple numbered tiles.""" from satpy.tests.utils import CustomScheduler from satpy.writers.awips_tiled import AWIPSTiledWriter data = _get_test_data() area_def = _get_test_area() input_data_arr = _get_test_lcc_data(data, area_def) w = AWIPSTiledWriter(base_dir=str(tmp_path), compress=True) save_kwargs = dict(sector_id='TEST', source_name="TESTS", tile_count=tile_count, tile_size=tile_size, extra_global_attrs={'my_global': 'TEST'}) should_error = tile_count is None and tile_size is None if should_error: with dask.config.set(scheduler=CustomScheduler(0)),\ pytest.raises(ValueError, match=r'Either.*tile_count.*'): w.save_datasets([input_data_arr], **save_kwargs) else: with dask.config.set( scheduler=CustomScheduler(1 * 2)): # precompute=*2 w.save_datasets([input_data_arr], **save_kwargs) all_files = glob(os.path.join(str(tmp_path), 'TESTS_AII*.nc')) expected_num_files = 0 if should_error else 9 assert len(all_files) == expected_num_files for fn in all_files: unmasked_ds = xr.open_dataset(fn, mask_and_scale=False) masked_ds = xr.open_dataset(fn, mask_and_scale=True) check_required_properties(unmasked_ds, masked_ds) assert unmasked_ds.attrs['my_global'] == 'TEST' assert unmasked_ds.attrs['sector_id'] == 'TEST' assert 'physical_element' in unmasked_ds.attrs stime = input_data_arr.attrs['start_time'] assert unmasked_ds.attrs['start_date_time'] == stime.strftime( '%Y-%m-%dT%H:%M:%S')
def test_lettered_tiles_update_existing(self): """Test updating lettered tiles with additional data.""" import shutil import dask import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter first_base_dir = os.path.join(self.base_dir, 'first') w = AWIPSTiledWriter(base_dir=first_base_dir, compress=True) shape = (2000, 1000) data = np.linspace(0., 1., shape[0] * shape[1], dtype=np.float32).reshape(shape) # pixels to be filled in later data[:, -200:] = np.nan data = da.from_array(data, chunks=500) area_def = self._get_test_area(shape=(2000, 1000), extents=(-1000000., -1500000., 1000000., 1500000.)) ds = self._get_test_lcc_data(data, area_def) # tile_count should be ignored since we specified lettered_grid w.save_datasets([ds], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) all_files = sorted(glob(os.path.join(first_base_dir, 'TESTS_AII*.nc'))) assert len(all_files) == 16 first_files = [] second_base_dir = os.path.join(self.base_dir, 'second') os.makedirs(second_base_dir) for fn in all_files: new_fn = fn.replace(first_base_dir, second_base_dir) shutil.copy(fn, new_fn) first_files.append(new_fn) # Second writing/updating # Area is about 100 pixels to the right area_def2 = self._get_test_area(shape=(2000, 1000), extents=(-800000., -1500000., 1200000., 1500000.)) data2 = np.linspace(0., 1., 2000000, dtype=np.float32).reshape( (2000, 1000)) # a gap at the beginning where old values remain data2[:, :200] = np.nan # a gap at the end where old values remain data2[:, -400:-300] = np.nan data2 = da.from_array(data2, chunks=500) ds2 = self._get_test_lcc_data(data2, area_def2) w = AWIPSTiledWriter(base_dir=second_base_dir, compress=True) # HACK: The _copy_to_existing function hangs when opening the output # file multiple times...sometimes. If we limit dask to one worker # it seems to work fine. with dask.config.set(num_workers=1): w.save_datasets([ds2], sector_id='LCC', source_name="TESTS", tile_count=(3, 3), lettered_grid=True) all_files = glob(os.path.join(second_base_dir, 'TESTS_AII*.nc')) # 16 original tiles + 4 new tiles assert len(all_files) == 20 # these tiles should be the right-most edge of the first image first_right_edge_files = [ x for x in first_files if 'P02' in x or 'P04' in x or 'V02' in x or 'V04' in x ] for new_file in first_right_edge_files: orig_file = new_file.replace(second_base_dir, first_base_dir) orig_nc = xr.open_dataset(orig_file) orig_data = orig_nc['data'].values if not np.isnan(orig_data).any(): # we only care about the tiles that had NaNs originally continue new_nc = xr.open_dataset(new_file) new_data = new_nc['data'].values # there should be at least some areas of the file # that old data was present and hasn't been replaced np.testing.assert_allclose(orig_data[:, :20], new_data[:, :20]) # it isn't exactly 200 because the tiles aren't aligned with the # data (the left-most tile doesn't have data until some columns # in), but it should be at least that many columns assert np.isnan(orig_data[:, 200:]).all() assert not np.isnan(new_data[:, 200:]).all()
def test_multivar_numbered_tiles_glm(self, sector): """Test creating a tiles with multiple variables.""" import xarray as xr from satpy.writers.awips_tiled import AWIPSTiledWriter from xarray import DataArray from pyresample.geometry import AreaDefinition from pyresample.utils import proj4_str_to_dict w = AWIPSTiledWriter(base_dir=self.base_dir, compress=True) area_def = AreaDefinition( 'test', 'test', 'test', proj4_str_to_dict( '+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. ' '+lat_0=25 +lat_1=25 +units=m +no_defs'), 100, 200, (-1000., -1500., 1000., 1500.), ) now = datetime(2018, 1, 1, 12, 0, 0) end_time = now + timedelta(minutes=20) ds1 = DataArray(da.from_array(np.linspace(0., 1., 20000, dtype=np.float32).reshape( (200, 100)), chunks=50), attrs=dict(name='total_energy', platform_name='GOES-17', sensor='SENSOR', units='1', area=area_def, start_time=now, end_time=end_time, scan_mode='M3', scene_abbr=sector, platform_shortname="G17")) ds2 = ds1.copy() ds2.attrs.update({ 'name': 'flash_extent_density', }) ds3 = ds1.copy() ds3.attrs.update({ 'name': 'average_flash_area', }) dqf = ds1.copy() dqf = (dqf * 255).astype(np.uint8) dqf.attrs = ds1.attrs.copy() dqf.attrs.update({ 'name': 'DQF', '_FillValue': 1, }) w.save_datasets([ds1, ds2, ds3, dqf], sector_id='TEST', source_name="TESTS", tile_count=(3, 3), template='glm_l2_rad{}'.format(sector.lower())) all_files = glob(os.path.join(self.base_dir, '*_GLM*.nc')) assert len(all_files) == 9 for fn in all_files: ds = xr.open_dataset(fn, mask_and_scale=False) check_required_common_attributes(ds) if sector == 'C': assert ds.attrs['time_coverage_end'] == end_time.strftime( '%Y-%m-%dT%H:%M:%S.%fZ') else: # 'F' assert ds.attrs['time_coverage_end'] == end_time.strftime( '%Y-%m-%dT%H:%M:%SZ')