class_docstr: Test basic functionality of AWIPS Tiled writer.
class_docstr_tok: ["Test","basic","functionality","of","AWIPS","Tiled","writer","."]
docstr: Test updating lettered tiles with additional data.
docstr_tok: ["Test","updating","lettered","tiles","with","additional","data","."]
code: def test_lettered_tiles_update_existing(self, tmp_path):
      """Test updating lettered tiles with additional data."""
      from satpy.writers.awips_tiled import AWIPSTiledWriter
  
      first_base_dir = os.path.join(str(tmp_path), "first")
      w = AWIPSTiledWriter(base_dir=first_base_dir, compress=True)
      shape = (2000, 1000)
      data = np.linspace(
          0.0, 1.0, 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 = _get_test_area(
          shape=(2000, 1000),
          extents=(-1000000.0, -1500000.0, 1000000.0, 1500000.0),
      )
      ds = _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(str(tmp_path), "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 = _get_test_area(
          shape=(2000, 1000),
          extents=(-800000.0, -1500000.0, 1200000.0, 1500000.0),
      )
      data2 = np.linspace(0.0, 1.0, 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 = _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()
  
imports: import logging
  import os
  import shutil
  from datetime import datetime, timedelta
  from glob import glob
  import dask
  import dask.array
  import numpy
  import pytest
  import xarray
  from pyproj import CRS
  from satpy.resample import update_resampled_coords
label_desc: Use image node_id 7 for calling the TestAWIPSTiledWriter obj's underlying member method code with example usage: obj.test_lettered_tiles_update_existing(tmp_path) without return types