ECOv003-L2T-STARS 1.3.0__tar.gz → 1.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/L2T_STARS.py +8 -23
  2. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/Project.toml +0 -4
  3. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP09GA.py +2 -2
  4. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/VNP43NRT.py +9 -4
  5. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/constants.py +1 -0
  6. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/generate_STARS_inputs.py +233 -0
  7. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/generate_downsampled_filename.py +20 -0
  8. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/load_prior.py +4 -4
  9. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/main.py +7 -0
  10. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_ECOSTRESS_data_fusion_distributed_bias.jl +19 -26
  11. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_STARS_product.py +26 -40
  12. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_julia_data_fusion.py +9 -7
  13. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/PKG-INFO +1 -1
  14. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/SOURCES.txt +1 -5
  15. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/PKG-INFO +1 -1
  16. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/pyproject.toml +1 -1
  17. ecov003_l2t_stars-1.3.0/ECOv003_L2T_STARS/generate_NDVI_coarse_directory.py +0 -21
  18. ecov003_l2t_stars-1.3.0/ECOv003_L2T_STARS/generate_NDVI_fine_directory.py +0 -14
  19. ecov003_l2t_stars-1.3.0/ECOv003_L2T_STARS/generate_STARS_inputs.py +0 -231
  20. ecov003_l2t_stars-1.3.0/ECOv003_L2T_STARS/generate_albedo_coarse_directory.py +0 -18
  21. ecov003_l2t_stars-1.3.0/ECOv003_L2T_STARS/generate_albedo_fine_directory.py +0 -17
  22. ecov003_l2t_stars-1.3.0/ECOv003_L2T_STARS/install_STARSDataFusion_jl.py +0 -43
  23. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/.github/workflows/ci.yml +0 -0
  24. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/.github/workflows/python-publish.yml +0 -0
  25. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/.gitignore +0 -0
  26. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/Dockerfile +0 -0
  27. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOSTRESS Granule Download Bias.ipynb +0 -0
  28. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOSTRESS Granule Download.ipynb +0 -0
  29. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/BRDF.py +0 -0
  30. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/SZA.py +0 -0
  31. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/__init__.py +0 -0
  32. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/statistical_radiative_transport.txt +0 -0
  33. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/version.txt +0 -0
  34. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_DL.py +0 -0
  35. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_DL.xml +0 -0
  36. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_L2T_STARS.xml +0 -0
  37. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/L2TSTARSConfig.py +0 -0
  38. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/LPDAACDataPool.py +0 -0
  39. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/__init__.py +0 -0
  40. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/version.txt +0 -0
  41. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/Manifest.toml +0 -0
  42. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VIIRSDataPool.py +0 -0
  43. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VIIRSDownloader.py +0 -0
  44. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP43IA4.py +0 -0
  45. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP43MA3.py +0 -0
  46. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/__init__.py +0 -0
  47. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/version.txt +0 -0
  48. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/__init__.py +0 -0
  49. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/process_VNP43NRT.jl +0 -0
  50. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/version.txt +0 -0
  51. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/Manifest.toml +0 -0
  52. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/Project.toml +0 -0
  53. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/__init__.py +0 -0
  54. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.jl +0 -0
  55. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.py +0 -0
  56. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/src/VNP43NRT.jl +0 -0
  57. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/src/__init__.py +0 -0
  58. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/__init__.py +0 -0
  59. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/calibrate_fine_to_coarse.py +0 -0
  60. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/cksum.py +0 -0
  61. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/daterange/__init__.py +0 -0
  62. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/daterange/daterange.py +0 -0
  63. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/exceptions.py +0 -0
  64. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_L2T_STARS_runconfig.py +0 -0
  65. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_NDVI_coarse_image.py +0 -0
  66. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_NDVI_fine_image.py +0 -0
  67. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_albedo_coarse_image.py +0 -0
  68. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_albedo_fine_image.py +0 -0
  69. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_filename.py +0 -0
  70. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_input_staging_directory.py +0 -0
  71. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_model_state_tile_date_directory.py +0 -0
  72. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_output_directory.py +0 -0
  73. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/instantiate_STARSDataFusion_jl.py +0 -0
  74. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/login.py +0 -0
  75. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/prior.py +0 -0
  76. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/retrieve_STARS_sources.py +0 -0
  77. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/runconfig.py +0 -0
  78. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/timer/__init__.py +0 -0
  79. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/timer/timer.py +0 -0
  80. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/version.py +0 -0
  81. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/version.txt +0 -0
  82. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/dependency_links.txt +0 -0
  83. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/entry_points.txt +0 -0
  84. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/requires.txt +0 -0
  85. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/top_level.txt +0 -0
  86. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/LICENSE +0 -0
  87. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/README.md +0 -0
  88. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/STARS_memory_profile.jpeg +0 -0
  89. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/demo.py +0 -0
  90. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/example_L2T_STARS_with_download.py +0 -0
  91. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/makefile +0 -0
  92. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/mprofile_20241202193217.dat +0 -0
  93. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/mprofile_20241203112611.dat +0 -0
  94. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/setup.cfg +0 -0
  95. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/tests/test_import_ECOv003_L2T_STARS.py +0 -0
  96. {ecov003_l2t_stars-1.3.0 → ecov003_l2t_stars-1.4.0}/tests/test_import_dependencies.py +0 -0
@@ -35,10 +35,6 @@ from .VNP43NRT import VNP43NRT
35
35
  from .runconfig import ECOSTRESSRunConfig
36
36
  from .L2TSTARSConfig import L2TSTARSConfig
37
37
  from .load_prior import load_prior
38
- from .generate_NDVI_coarse_directory import generate_NDVI_coarse_directory
39
- from .generate_NDVI_fine_directory import generate_NDVI_fine_directory
40
- from .generate_albedo_coarse_directory import generate_albedo_coarse_directory
41
- from .generate_albedo_fine_directory import generate_albedo_fine_directory
42
38
  from .generate_STARS_inputs import generate_STARS_inputs
43
39
  from .process_STARS_product import process_STARS_product
44
40
  from .retrieve_STARS_sources import retrieve_STARS_sources
@@ -58,6 +54,7 @@ def L2T_STARS(
58
54
  remove_input_staging: bool = True,
59
55
  remove_prior: bool = True,
60
56
  remove_posterior: bool = True,
57
+ initialize_julia: bool = False,
61
58
  threads: Union[int, str] = "auto",
62
59
  num_workers: int = 4,
63
60
  overwrite: bool = False, # New parameter for overwriting existing files
@@ -240,6 +237,8 @@ def L2T_STARS(
240
237
  logger.info(f"VNP09GA products directory: {cl.dir(VNP09GA_products_directory)}")
241
238
  VNP43NRT_products_directory = join(sources_directory, DEFAULT_VNP43NRT_PRODUCTS_DIRECTORY)
242
239
  logger.info(f"VNP43NRT products directory: {cl.dir(VNP43NRT_products_directory)}")
240
+ DOWNSAMPLED_products_directory = join(sources_directory, DEFAULT_STARS_DOWNSAMPLED_DIRECTORY)
241
+ logger.info(f"DOWNSAMPLED products directory: {cl.dir(DOWNSAMPLED_products_directory)}")
243
242
 
244
243
  # Re-check for existing product (double-check in case another process created it) with overwrite option
245
244
  if not overwrite and exists(L2T_STARS_zip_filename):
@@ -283,6 +282,7 @@ def L2T_STARS(
283
282
  GEOS5FP_products=GEOS5FP_products_directory,
284
283
  VNP09GA_directory=VNP09GA_products_directory,
285
284
  VNP43NRT_directory=VNP43NRT_products_directory,
285
+ initialize_julia=initialize_julia,
286
286
  )
287
287
 
288
288
  albedo_VIIRS_connection = VNP43NRT(
@@ -293,6 +293,7 @@ def L2T_STARS(
293
293
  GEOS5FP_products=GEOS5FP_products_directory,
294
294
  VNP09GA_directory=VNP09GA_products_directory,
295
295
  VNP43NRT_directory=VNP43NRT_products_directory,
296
+ initialize_julia=initialize_julia,
296
297
  )
297
298
  except CMRServerUnreachable as e:
298
299
  logger.exception(e)
@@ -404,19 +405,6 @@ def L2T_STARS(
404
405
  NDVI_coarse_geometry = HLS_connection.grid(tile=tile, cell_size=NDVI_resolution)
405
406
  albedo_coarse_geometry = HLS_connection.grid(tile=tile, cell_size=albedo_resolution)
406
407
 
407
- NDVI_coarse_directory = generate_NDVI_coarse_directory(
408
- input_staging_directory=input_staging_directory, tile=tile
409
- )
410
- NDVI_fine_directory = generate_NDVI_fine_directory(
411
- input_staging_directory=input_staging_directory, tile=tile
412
- )
413
- albedo_coarse_directory = generate_albedo_coarse_directory(
414
- input_staging_directory=input_staging_directory, tile=tile
415
- )
416
- albedo_fine_directory = generate_albedo_fine_directory(
417
- input_staging_directory=input_staging_directory, tile=tile
418
- )
419
-
420
408
  generate_STARS_inputs(
421
409
  tile=tile,
422
410
  date_UTC=date_UTC,
@@ -429,11 +417,7 @@ def L2T_STARS(
429
417
  target_resolution=target_resolution,
430
418
  NDVI_coarse_geometry=NDVI_coarse_geometry,
431
419
  albedo_coarse_geometry=albedo_coarse_geometry,
432
- working_directory=working_directory,
433
- NDVI_coarse_directory=NDVI_coarse_directory,
434
- NDVI_fine_directory=NDVI_fine_directory,
435
- albedo_coarse_directory=albedo_coarse_directory,
436
- albedo_fine_directory=albedo_fine_directory,
420
+ downsampled_directory=DOWNSAMPLED_products_directory,
437
421
  HLS_connection=HLS_connection,
438
422
  NDVI_VIIRS_connection=NDVI_VIIRS_connection,
439
423
  albedo_VIIRS_connection=albedo_VIIRS_connection,
@@ -454,7 +438,7 @@ def L2T_STARS(
454
438
  NDVI_resolution=NDVI_resolution,
455
439
  albedo_resolution=albedo_resolution,
456
440
  target_resolution=target_resolution,
457
- working_directory=working_directory,
441
+ downsampled_directory=DOWNSAMPLED_products_directory,
458
442
  model_directory=model_directory,
459
443
  input_staging_directory=input_staging_directory,
460
444
  L2T_STARS_granule_directory=L2T_STARS_granule_directory,
@@ -470,6 +454,7 @@ def L2T_STARS(
470
454
  remove_input_staging=remove_input_staging,
471
455
  remove_prior=remove_prior,
472
456
  remove_posterior=remove_posterior,
457
+ initialize_julia=initialize_julia,
473
458
  threads=threads,
474
459
  num_workers=num_workers,
475
460
  )
@@ -3,12 +3,8 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
3
3
  DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
4
4
  Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
5
5
  Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
6
- HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
7
- JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
8
6
  LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
9
7
  Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
10
- OpenSSL = "4d8831e6-92b7-49fb-bdf8-b643e874388c"
11
- Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
12
8
  Rasters = "a3a2b9e3-a471-40c9-b274-f788e487c689"
13
9
  STARSDataFusion = "70ccc657-289f-4534-a407-e03a16fd1153"
14
10
  Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
@@ -1096,7 +1096,7 @@ class VNP09GA:
1096
1096
 
1097
1097
  self.resampling = resampling
1098
1098
 
1099
- self._granules = pd.DataFrame({"date_UTC": {}, "tile": {}, "granule": {}})
1099
+ self._granules = pd.DataFrame(columns=["date_UTC", "tile", "granule"])
1100
1100
 
1101
1101
  if working_directory is None:
1102
1102
  working_directory = self.DEFAULT_WORKING_DIRECTORY
@@ -1233,7 +1233,7 @@ class VNP09GA:
1233
1233
  if "date_UTC" not in self._granules.columns:
1234
1234
  raise ValueError(f"date_UTC column not in granules table")
1235
1235
 
1236
- subset = self._granules[(self._granules.date_UTC == date_UTC) & (self._granules.tile == tile)]
1236
+ subset = self._granules[(self._granules['date_UTC'] == date_UTC) & (self._granules['tile'] == tile)]
1237
1237
  if len(subset) > 0:
1238
1238
  return subset.iloc[0].granule
1239
1239
 
@@ -106,12 +106,14 @@ def process_julia_BRDF(
106
106
  sensor_zenith_directory: str,
107
107
  relative_azimuth_directory: str,
108
108
  SZA_filename: str,
109
- output_directory: str):
109
+ output_directory: str,
110
+ initialize_julia: bool):
110
111
  parent_directory = abspath(join(dirname(__file__), ".."))
111
112
  julia_source_directory = join(parent_directory, "VNP43NRT_jl")
112
113
  julia_script_filename = join(abspath(dirname(__file__)), "process_VNP43NRT.jl")
113
114
 
114
- instantiate_VNP43NRT_jl(julia_source_directory)
115
+ if initialize_julia:
116
+ instantiate_VNP43NRT_jl(julia_source_directory)
115
117
 
116
118
  command = f'julia "{julia_script_filename}" "{band}" "{h}" "{v}" "{tile_width_cells}" "{start_date:%Y-%m-%d}" "{end_date:%Y-%m-%d}" "{reflectance_directory}" "{solar_zenith_directory}" "{sensor_zenith_directory}" "{relative_azimuth_directory}" "{SZA_filename}" "{output_directory}"'
117
119
  logger.info(command)
@@ -265,7 +267,8 @@ class VNP43NRT(VIIRSDownloaderAlbedo, VIIRSDownloaderNDVI):
265
267
  VNP43NRT_staging_directory: str = None,
266
268
  GEOS5FP_connection: GEOS5FP = None,
267
269
  GEOS5FP_download: str = None,
268
- GEOS5FP_products: str = None):
270
+ GEOS5FP_products: str = None,
271
+ initialize_julia: bool = False):
269
272
  if working_directory is None:
270
273
  working_directory = VNP09GA.DEFAULT_WORKING_DIRECTORY
271
274
 
@@ -302,6 +305,7 @@ class VNP43NRT(VIIRSDownloaderAlbedo, VIIRSDownloaderNDVI):
302
305
  self.VNP43NRT_directory = VNP43NRT_directory
303
306
  self.GEOS5FP = GEOS5FP_connection
304
307
  self.VNP43NRT_staging_directory = VNP43NRT_staging_directory
308
+ self.initialize_julia = initialize_julia
305
309
 
306
310
  def __repr__(self):
307
311
  display_dict = {
@@ -493,7 +497,8 @@ class VNP43NRT(VIIRSDownloaderAlbedo, VIIRSDownloaderNDVI):
493
497
  sensor_zenith_directory=sensor_zenith_directory,
494
498
  relative_azimuth_directory=relative_azimuth_directory,
495
499
  SZA_filename=SZA_filename,
496
- output_directory=output_directory
500
+ output_directory=output_directory,
501
+ initialize_julia=self.initialize_julia,
497
502
  )
498
503
 
499
504
  WSA = Raster.open(join(output_directory, f"{date_UTC:%Y-%m-%d}_WSA.tif"))
@@ -22,6 +22,7 @@ DEFAULT_GEOS5FP_DOWNLOAD_DIRECTORY = "GEOS5FP_download"
22
22
  DEFAULT_GEOS5FP_PRODUCTS_DIRECTORY = "GEOS5FP_products"
23
23
  DEFAULT_VNP09GA_PRODUCTS_DIRECTORY = "VNP09GA_products"
24
24
  DEFAULT_VNP43NRT_PRODUCTS_DIRECTORY = "VNP43NRT_products"
25
+ DEFAULT_STARS_DOWNSAMPLED_DIRECTORY = "DOWNSAMPLED_products"
25
26
 
26
27
  # Processing parameters
27
28
  VIIRS_GIVEUP_DAYS = 4 # Number of days to give up waiting for VIIRS data
@@ -0,0 +1,233 @@
1
+ from typing import Union
2
+ from datetime import date, datetime
3
+ from dateutil.rrule import rrule, DAILY
4
+ from os.path import exists
5
+ import logging
6
+
7
+ import colored_logging as cl
8
+ from rasters import Raster, RasterGeometry
9
+ from harmonized_landsat_sentinel import HLS2CMR
10
+
11
+ from ECOv003_exit_codes import AuxiliaryLatency
12
+
13
+ from .constants import VIIRS_GIVEUP_DAYS
14
+ from .generate_filename import generate_filename
15
+ from .daterange import get_date
16
+ from .generate_NDVI_coarse_image import generate_NDVI_coarse_image
17
+ from .generate_NDVI_fine_image import generate_NDVI_fine_image
18
+ from .generate_albedo_coarse_image import generate_albedo_coarse_image
19
+ from .generate_albedo_fine_image import generate_albedo_fine_image
20
+ from .generate_downsampled_filename import generate_downsampled_filename
21
+ from .calibrate_fine_to_coarse import calibrate_fine_to_coarse
22
+ from .VIIRS.VIIRSDownloader import VIIRSDownloaderAlbedo, VIIRSDownloaderNDVI
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+ def generate_STARS_inputs(
27
+ tile: str,
28
+ date_UTC: date,
29
+ HLS_start_date: date,
30
+ HLS_end_date: date,
31
+ VIIRS_start_date: date,
32
+ VIIRS_end_date: date,
33
+ NDVI_resolution: int,
34
+ albedo_resolution: int,
35
+ target_resolution: int,
36
+ NDVI_coarse_geometry: RasterGeometry,
37
+ albedo_coarse_geometry: RasterGeometry,
38
+ downsampled_directory: str,
39
+ HLS_connection: HLS2CMR,
40
+ NDVI_VIIRS_connection: VIIRSDownloaderNDVI,
41
+ albedo_VIIRS_connection: VIIRSDownloaderAlbedo,
42
+ calibrate_fine: bool = False,
43
+ ):
44
+ """
45
+ Generates and stages the necessary coarse and fine resolution input images
46
+ for the STARS data fusion process.
47
+
48
+ This function iterates through the VIIRS date range, retrieving and saving
49
+ coarse NDVI and albedo images. For dates within the HLS range, it also
50
+ retrieves and saves fine NDVI and albedo images. It can optionally
51
+ calibrate the fine images to the coarse images.
52
+
53
+ Args:
54
+ tile (str): The HLS tile ID.
55
+ date_UTC (date): The target UTC date for the L2T_STARS product.
56
+ HLS_start_date (date): The start date for HLS data retrieval for the fusion period.
57
+ HLS_end_date (date): The end date for HLS data retrieval for the fusion period.
58
+ VIIRS_start_date (date): The start date for VIIRS data retrieval for the fusion period.
59
+ VIIRS_end_date (date): The end date for VIIRS data retrieval for the fusion period.
60
+ NDVI_resolution (int): The resolution of the coarse NDVI data.
61
+ albedo_resolution (int): The resolution of the coarse albedo data.
62
+ target_resolution (int): The desired output resolution of the fused product.
63
+ NDVI_coarse_geometry (RasterGeometry): The target geometry for coarse NDVI images.
64
+ albedo_coarse_geometry (RasterGeometry): The target geometry for coarse albedo images.
65
+ working_directory (str): The main working directory.
66
+ NDVI_coarse_directory (str): Directory for staging coarse NDVI images.
67
+ NDVI_fine_directory (str): Directory for staging fine NDVI images.
68
+ albedo_coarse_directory (str): Directory for staging coarse albedo images.
69
+ albedo_fine_directory (str): Directory for staging fine albedo images.
70
+ HLS_connection (HLS2CMR): An initialized HLS data connection object.
71
+ NDVI_VIIRS_connection (VIIRSDownloaderNDVI): An initialized VIIRS NDVI downloader.
72
+ albedo_VIIRS_connection (VIIRSDownloaderAlbedo): An initialized VIIRS albedo downloader.
73
+ calibrate_fine (bool, optional): If True, calibrate fine images to coarse images.
74
+ Defaults to False.
75
+
76
+ Raises:
77
+ AuxiliaryLatency: If coarse VIIRS data is missing within the VIIRS_GIVEUP_DAYS window.
78
+ """
79
+ missing_coarse_dates = set() # Track dates where coarse data could not be generated
80
+
81
+ logger.info(f"preparing coarse and fine images for STARS at {cl.place(tile)}")
82
+
83
+ # Process each day within the VIIRS data fusion window
84
+ for processing_date in [
85
+ get_date(dt) for dt in rrule(DAILY, dtstart=VIIRS_start_date, until=VIIRS_end_date)
86
+ ]:
87
+ NDVI_coarse_filename = generate_downsampled_filename(
88
+ directory=downsampled_directory,
89
+ variable="NDVI",
90
+ date_UTC=processing_date,
91
+ tile=tile,
92
+ cell_size=NDVI_resolution
93
+ )
94
+
95
+ NDVI_fine_filename = generate_downsampled_filename(
96
+ directory=downsampled_directory,
97
+ variable="NDVI",
98
+ date_UTC=processing_date,
99
+ tile=tile,
100
+ cell_size=target_resolution
101
+ )
102
+
103
+ albedo_coarse_filename = generate_downsampled_filename(
104
+ directory=downsampled_directory,
105
+ variable="albedo",
106
+ date_UTC=processing_date,
107
+ tile=tile,
108
+ cell_size=albedo_resolution
109
+ )
110
+
111
+ albedo_fine_filename = generate_downsampled_filename(
112
+ directory=downsampled_directory,
113
+ variable="albedo",
114
+ date_UTC=processing_date,
115
+ tile=tile,
116
+ cell_size=target_resolution
117
+ )
118
+
119
+ try:
120
+ # Cache whether the NDVI coarse exists to avoid ToCToU
121
+ NDVI_coarse_exists = exists(NDVI_coarse_filename)
122
+ if not NDVI_coarse_exists:
123
+ logger.info(f"preparing coarse image for STARS NDVI at {cl.place(tile)} on {cl.time(processing_date)}")
124
+
125
+ NDVI_coarse_image = generate_NDVI_coarse_image(
126
+ date_UTC=processing_date,
127
+ VIIRS_connection=NDVI_VIIRS_connection,
128
+ geometry=NDVI_coarse_geometry
129
+ )
130
+
131
+ logger.info(
132
+ f"saving coarse image for STARS NDVI at {cl.place(tile)} on {cl.time(processing_date)}: {NDVI_coarse_filename}")
133
+ NDVI_coarse_image.to_geotiff(NDVI_coarse_filename)
134
+
135
+ if processing_date >= HLS_start_date:
136
+ try:
137
+ if not exists(NDVI_fine_filename):
138
+ logger.info(
139
+ f"preparing fine image for STARS NDVI at {cl.place(tile)} on {cl.time(processing_date)}")
140
+
141
+ NDVI_fine_image = generate_NDVI_fine_image(
142
+ date_UTC=processing_date,
143
+ tile=tile,
144
+ HLS_connection=HLS_connection
145
+ )
146
+
147
+ if calibrate_fine:
148
+ # Ensure that the NDVI_coarse_image variable is set
149
+ if NDVI_coarse_exists:
150
+ NDVI_coarse_image = Raster.open(NDVI_coarse_filename)
151
+ logger.info(
152
+ f"calibrating fine image for STARS NDVI at {cl.place(tile)} on {cl.time(processing_date)}")
153
+ NDVI_fine_image = calibrate_fine_to_coarse(NDVI_fine_image, NDVI_coarse_image)
154
+
155
+ logger.info(
156
+ f"saving fine image for STARS NDVI at {cl.place(tile)} on {cl.time(processing_date)}: {NDVI_fine_filename}")
157
+ NDVI_fine_image.to_geotiff(NDVI_fine_filename)
158
+ except Exception: # Catch any exception during HLS fine image generation
159
+ logger.info(f"HLS NDVI is not available on {processing_date}")
160
+ except Exception as e:
161
+ logger.exception(e)
162
+ logger.warning(
163
+ f"Unable to produce coarse NDVI for date {processing_date}"
164
+ )
165
+ missing_coarse_dates.add(processing_date) # Add date to missing set
166
+
167
+ try:
168
+ # Cache whether the albedo coarse exists to avoid ToCToU
169
+ albedo_coarse_exists = exists(albedo_coarse_filename)
170
+ if not albedo_coarse_exists:
171
+ logger.info(
172
+ f"preparing coarse image for STARS albedo at {cl.place(tile)} on {cl.time(processing_date)}")
173
+
174
+ albedo_coarse_image = generate_albedo_coarse_image(
175
+ date_UTC=processing_date,
176
+ VIIRS_connection=albedo_VIIRS_connection,
177
+ geometry=albedo_coarse_geometry
178
+ )
179
+
180
+ logger.info(
181
+ f"saving coarse image for STARS albedo at {cl.place(tile)} on {cl.time(processing_date)}: {albedo_coarse_filename}")
182
+ albedo_coarse_image.to_geotiff(albedo_coarse_filename)
183
+
184
+ if processing_date >= HLS_start_date:
185
+ try:
186
+ if not exists(albedo_fine_filename):
187
+ logger.info(
188
+ f"preparing fine image for STARS albedo at {cl.place(tile)} on {cl.time(processing_date)}")
189
+
190
+ albedo_fine_image = generate_albedo_fine_image(
191
+ date_UTC=processing_date,
192
+ tile=tile,
193
+ HLS_connection=HLS_connection
194
+ )
195
+
196
+ if calibrate_fine:
197
+ # Ensure that the albedo_coarse_image variable is set
198
+ if albedo_coarse_exists:
199
+ albedo_coarse_image = Raster.open(albedo_coarse_filename)
200
+
201
+ logger.info(
202
+ f"calibrating fine image for STARS albedo at {cl.place(tile)} on {cl.time(processing_date)}")
203
+ albedo_fine_image = calibrate_fine_to_coarse(albedo_fine_image, albedo_coarse_image)
204
+
205
+ logger.info(
206
+ f"saving fine image for STARS albedo at {cl.place(tile)} on {cl.time(processing_date)}: {albedo_fine_filename}")
207
+ albedo_fine_image.to_geotiff(albedo_fine_filename)
208
+ except Exception: # Catch any exception during HLS fine image generation
209
+ logger.info(f"HLS albedo is not available on {processing_date}")
210
+ except Exception as e:
211
+ logger.exception(e)
212
+ logger.warning(
213
+ f"Unable to produce coarse albedo for date {processing_date}"
214
+ )
215
+ missing_coarse_dates.add(processing_date) # Add date to missing set
216
+
217
+ # We need to deal with the possibility that VIIRS has not yet published their data yet.
218
+ # VIIRS_GIVEUP_DAYS is the number of days before we assume that missing observations aren't coming.
219
+ # If any missing days are closer to now than VIIRS_GIVEUP_DAYS, we want to retry this run later, when VIIRS
220
+ # might have uploaded the missing observations. To cause this retry, we'll throw the `AncillaryLatency` exception.
221
+ # L2T_STARS converts this exception to an exit code, and the orchestration system marks this run
222
+ # as needing a retry at a later date.
223
+ coarse_latency_dates = [
224
+ d
225
+ for d in missing_coarse_dates
226
+ if (datetime.utcnow().date() - d).days <= VIIRS_GIVEUP_DAYS
227
+ ]
228
+
229
+ if len(coarse_latency_dates) > 0:
230
+ raise AuxiliaryLatency(
231
+ f"Missing coarse dates within {VIIRS_GIVEUP_DAYS}-day window: "
232
+ f"{', '.join([str(d) for d in sorted(list(coarse_latency_dates))])}"
233
+ )
@@ -0,0 +1,20 @@
1
+ from os import makedirs
2
+ from os.path import join, dirname
3
+ from dateutil import parser
4
+ from datetime import date
5
+
6
+ from typing import Union
7
+
8
+ def generate_downsampled_filename(directory: str, variable: str, date_UTC: Union[date, str], tile: str, cell_size: int) -> str:
9
+ if isinstance(date_UTC, str):
10
+ date_UTC = parser.parse(date_UTC).date()
11
+
12
+ variable = str(variable)
13
+ year = str(date_UTC.year)
14
+ timestamp = date_UTC.strftime("%Y-%m-%d")
15
+ tile = str(tile)
16
+ cell_size = int(cell_size)
17
+ filename = join(directory, year, timestamp, tile, f"STARS_{variable}_{tile}_{cell_size}m.tif")
18
+ makedirs(dirname(filename), exist_ok=True)
19
+
20
+ return filename
@@ -98,7 +98,7 @@ def load_prior(
98
98
  cell_size=target_resolution,
99
99
  )
100
100
  # Assuming L2T_STARS_prior_granule has a .NDVI_bias attribute
101
- if hasattr(L2T_STARS_prior_granule, "NDVI_bias") and L2T_STARS_prior_granule.NDVI_bias is not None:
101
+ if L2T_STARS_prior_granule.NDVI_bias is not None:
102
102
  L2T_STARS_prior_granule.NDVI_bias.to_geotiff(prior_NDVI_bias_filename)
103
103
  else:
104
104
  prior_NDVI_bias_filename = None # Set to None if not available
@@ -111,7 +111,7 @@ def load_prior(
111
111
  cell_size=target_resolution,
112
112
  )
113
113
  # Assuming L2T_STARS_prior_granule has a .NDVI_bias_UQ attribute
114
- if hasattr(L2T_STARS_prior_granule, "NDVI_bias_UQ") and L2T_STARS_prior_granule.NDVI_bias_UQ is not None:
114
+ if L2T_STARS_prior_granule.NDVI_bias_UQ is not None:
115
115
  L2T_STARS_prior_granule.NDVI_bias_UQ.to_geotiff(prior_NDVI_bias_UQ_filename)
116
116
  else:
117
117
  prior_NDVI_bias_UQ_filename = None # Set to None if not available
@@ -143,7 +143,7 @@ def load_prior(
143
143
  cell_size=target_resolution,
144
144
  )
145
145
  # Assuming L2T_STARS_prior_granule has a .albedo_bias attribute
146
- if hasattr(L2T_STARS_prior_granule, "albedo_bias") and L2T_STARS_prior_granule.albedo_bias is not None:
146
+ if L2T_STARS_prior_granule.albedo_bias is not None:
147
147
  L2T_STARS_prior_granule.albedo_bias.to_geotiff(prior_albedo_bias_filename)
148
148
  else:
149
149
  prior_albedo_bias_filename = None # Set to None if not available
@@ -156,7 +156,7 @@ def load_prior(
156
156
  cell_size=target_resolution,
157
157
  )
158
158
  # Assuming L2T_STARS_prior_granule has a .albedo_bias_UQ attribute
159
- if hasattr(L2T_STARS_prior_granule, "albedo_bias_UQ") and L2T_STARS_prior_granule.albedo_bias_UQ is not None:
159
+ if L2T_STARS_prior_granule.albedo_bias_UQ is not None:
160
160
  L2T_STARS_prior_granule.albedo_bias_UQ.to_geotiff(prior_albedo_bias_UQ_filename)
161
161
  else:
162
162
  prior_albedo_bias_UQ_filename = None # Set to None if not available
@@ -115,6 +115,12 @@ def main():
115
115
  default=True,
116
116
  help="Do NOT remove posterior intermediate files after product generation.",
117
117
  )
118
+ parser.add_argument(
119
+ "--initialize-julia",
120
+ action="store_true",
121
+ dest="initialize_julia",
122
+ help="Initialize a julia environment before running julia.",
123
+ )
118
124
  parser.add_argument(
119
125
  "--threads",
120
126
  type=str,
@@ -157,6 +163,7 @@ def main():
157
163
  remove_input_staging=args.remove_input_staging,
158
164
  remove_prior=args.remove_prior,
159
165
  remove_posterior=args.remove_posterior,
166
+ initialize_julia=args.initialize_julia,
160
167
  threads=args.threads,
161
168
  num_workers=args.num_workers,
162
169
  overwrite=args.overwrite, # Pass the new overwrite argument
@@ -8,24 +8,8 @@ using STARSDataFusion.sentinel_tiles
8
8
  using STARSDataFusion.HLS
9
9
  using STARSDataFusion.VNP43
10
10
  using Logging
11
- using Pkg
12
11
  using Statistics
13
12
  using Distributed
14
- Pkg.add("OpenSSL")
15
- using HTTP
16
- using JSON
17
-
18
- function read_json(file::String)::Dict
19
- open(file, "r") do f
20
- return JSON.parse(f)
21
- end
22
- end
23
-
24
- function write_json(file::String, data::Dict)
25
- open(file, "w") do f
26
- JSON.print(f, data)
27
- end
28
- end
29
13
 
30
14
  @info "processing STARS data fusion"
31
15
 
@@ -78,10 +62,10 @@ HLS_start_date = Date(ARGS[7])
78
62
  @info "HLS start date: $(HLS_start_date)"
79
63
  HLS_end_date = Date(ARGS[8])
80
64
  @info "HLS end date: $(HLS_end_date)"
81
- coarse_directory = ARGS[9]
82
- @info "coarse inputs directory: $(coarse_directory)"
83
- fine_directory = ARGS[10]
84
- @info "fine inputs directory: $(fine_directory)"
65
+ downsampled_directory = ARGS[9]
66
+ @info "downsampled inputs directory: $(downsampled_directory)"
67
+ product_name = ARGS[10]
68
+ @info "Computing $(product_name) product"
85
69
  posterior_filename = ARGS[11]
86
70
  @info "posterior filename: $(posterior_filename)"
87
71
  posterior_UQ_filename = ARGS[12]
@@ -130,20 +114,29 @@ y_fine_size = size(y_fine)[1]
130
114
  @info "fine x size: $(x_fine_size)"
131
115
  @info "fine y size: $(y_fine_size)"
132
116
 
133
- coarse_image_filenames = sort(glob("*.tif", coarse_directory))
134
- coarse_dates_found = [Date(split(basename(filename), "_")[3]) for filename in coarse_image_filenames]
135
-
136
- fine_image_filenames = sort(glob("*.tif", fine_directory))
137
- fine_dates_found = [Date(split(basename(filename), "_")[3]) for filename in fine_image_filenames]
138
-
117
+ # The range of dates to check for VIIRS files
139
118
  coarse_start_date = VIIRS_start_date
140
119
  coarse_end_date = VIIRS_end_date
141
120
 
121
+ # Check each coarse date for a downsampled image
122
+ # For each day we find, convert the date directory back into a date object
123
+ coarse_dates = [coarse_start_date + Day(d - 1) for d in 1:((coarse_end_date - coarse_start_date).value + 1)]
124
+ coarse_image_filenames = [joinpath("$(downsampled_directory)", "$(year(date))", "$(Dates.format(date, dateformat"yyyy-mm-dd"))", "$(tile)", "STARS_$(product_name)_$(tile)_$(coarse_cell_size)m.tif") for date in coarse_dates]
125
+ coarse_image_filenames = [filename for filename in coarse_image_filenames if ispath(filename)]
126
+ coarse_dates_found = [Date(basename(dirname(dirname(filename)))) for filename in coarse_image_filenames]
127
+
128
+ # The range of dates to check for HLS files
142
129
  fine_flag_start_date = HLS_end_date - Day(7)
143
130
  fine_start_date = HLS_start_date
144
131
  fine_end_date = HLS_end_date
145
132
 
133
+ # Check each fine date for a downsampled image
134
+ # For each day we find, convert the date directory back into a date object
146
135
  dates = [fine_start_date + Day(d - 1) for d in 1:((fine_end_date - fine_start_date).value + 1)]
136
+ fine_image_filenames = [joinpath("$(downsampled_directory)", "$(year(date))", "$(Dates.format(date, dateformat"yyyy-mm-dd"))", "$(tile)", "STARS_$(product_name)_$(tile)_$(fine_cell_size)m.tif") for date in dates]
137
+ fine_image_filenames = [filename for filename in fine_image_filenames if ispath(filename)]
138
+ fine_dates_found = [Date(basename(dirname(dirname(filename)))) for filename in fine_image_filenames]
139
+
147
140
  t = Ti(dates)
148
141
  coarse_dims = (x_coarse, y_coarse, t)
149
142
  fine_dims = (x_fine, y_fine, t)