ECOv003-L2T-STARS 1.2.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 (99) hide show
  1. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/.github/workflows/ci.yml +6 -1
  2. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/L2T_STARS.py +9 -24
  3. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/LPDAACDataPool.py +42 -40
  4. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/Project.toml +0 -4
  5. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP09GA.py +5 -4
  6. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/VNP43NRT.py +9 -4
  7. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/__init__.py +1 -1
  8. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/cksum.py +66 -0
  9. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/constants.py +1 -0
  10. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/exceptions.py +2 -0
  11. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/generate_STARS_inputs.py +233 -0
  12. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/generate_downsampled_filename.py +20 -0
  13. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/instantiate_STARS_jl.py → ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/instantiate_STARSDataFusion_jl.py +3 -3
  14. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/load_prior.py +4 -4
  15. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/login.py +61 -0
  16. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/ECOv003_L2T_STARS.py → ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/main.py +7 -0
  17. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_ECOSTRESS_data_fusion_distributed_bias.jl +19 -26
  18. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_STARS_product.py +26 -40
  19. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_julia_data_fusion.py +10 -8
  20. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/PKG-INFO +1 -2
  21. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/SOURCES.txt +7 -9
  22. ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS.egg-info/entry_points.txt +3 -0
  23. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/requires.txt +0 -1
  24. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/PKG-INFO +1 -2
  25. ecov003_l2t_stars-1.4.0/makefile +90 -0
  26. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/pyproject.toml +2 -3
  27. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/tests/test_import_dependencies.py +0 -1
  28. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/VIIRS/VIIRS_CMR_LOGIN.py +0 -36
  29. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_NDVI_coarse_directory.py +0 -21
  30. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_NDVI_fine_directory.py +0 -14
  31. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_STARS_inputs.py +0 -231
  32. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_albedo_coarse_directory.py +0 -18
  33. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_albedo_fine_directory.py +0 -17
  34. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/install_STARS_jl.py +0 -43
  35. ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS.egg-info/entry_points.txt +0 -3
  36. ecov003_l2t_stars-1.2.0/makefile +0 -66
  37. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/.github/workflows/python-publish.yml +0 -0
  38. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/.gitignore +0 -0
  39. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/Dockerfile +0 -0
  40. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOSTRESS Granule Download Bias.ipynb +0 -0
  41. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOSTRESS Granule Download.ipynb +0 -0
  42. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/BRDF.py +0 -0
  43. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/SZA.py +0 -0
  44. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/__init__.py +0 -0
  45. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/statistical_radiative_transport.txt +0 -0
  46. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/version.txt +0 -0
  47. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_DL.py +0 -0
  48. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_DL.xml +0 -0
  49. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_L2T_STARS.xml +0 -0
  50. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/L2TSTARSConfig.py +0 -0
  51. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/__init__.py +0 -0
  52. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/version.txt +0 -0
  53. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/Manifest.toml +0 -0
  54. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VIIRSDataPool.py +0 -0
  55. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VIIRSDownloader.py +0 -0
  56. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP43IA4.py +0 -0
  57. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP43MA3.py +0 -0
  58. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/__init__.py +0 -0
  59. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/version.txt +0 -0
  60. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/__init__.py +0 -0
  61. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/process_VNP43NRT.jl +0 -0
  62. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/version.txt +0 -0
  63. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/Manifest.toml +0 -0
  64. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/Project.toml +0 -0
  65. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/__init__.py +0 -0
  66. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.jl +0 -0
  67. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.py +0 -0
  68. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/src/VNP43NRT.jl +0 -0
  69. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/src/__init__.py +0 -0
  70. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/calibrate_fine_to_coarse.py +0 -0
  71. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/daterange/__init__.py +0 -0
  72. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/daterange/daterange.py +0 -0
  73. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_L2T_STARS_runconfig.py +0 -0
  74. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_NDVI_coarse_image.py +0 -0
  75. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_NDVI_fine_image.py +0 -0
  76. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_albedo_coarse_image.py +0 -0
  77. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_albedo_fine_image.py +0 -0
  78. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_filename.py +0 -0
  79. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_input_staging_directory.py +0 -0
  80. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_model_state_tile_date_directory.py +0 -0
  81. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_output_directory.py +0 -0
  82. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/prior.py +0 -0
  83. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/retrieve_STARS_sources.py +0 -0
  84. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/runconfig.py +0 -0
  85. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/timer/__init__.py +0 -0
  86. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/timer/timer.py +0 -0
  87. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/version.py +0 -0
  88. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/version.txt +0 -0
  89. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/dependency_links.txt +0 -0
  90. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/top_level.txt +0 -0
  91. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/LICENSE +0 -0
  92. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/README.md +0 -0
  93. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/STARS_memory_profile.jpeg +0 -0
  94. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/demo.py +0 -0
  95. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/example_L2T_STARS_with_download.py +0 -0
  96. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/mprofile_20241202193217.dat +0 -0
  97. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/mprofile_20241203112611.dat +0 -0
  98. {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/setup.cfg +0 -0
  99. /ecov003_l2t_stars-1.2.0/tests/test_import_ECOv003_L3T_L4T_JET.py → /ecov003_l2t_stars-1.4.0/tests/test_import_ECOv003_L2T_STARS.py +0 -0
@@ -13,7 +13,7 @@ jobs:
13
13
  runs-on: ubuntu-latest
14
14
  strategy:
15
15
  matrix:
16
- python-version: ["3.10", "3.11"]
16
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
17
17
 
18
18
  steps:
19
19
  - name: Checkout repository
@@ -32,3 +32,8 @@ jobs:
32
32
  - name: Run tests
33
33
  run: |
34
34
  pytest
35
+ env:
36
+ PYTHONPATH: .
37
+ EARTHDATA_USERNAME: ${{ secrets.EARTHDATA_USERNAME }}
38
+ EARTHDATA_PASSWORD: ${{ secrets.EARTHDATA_PASSWORD }}
39
+ SKIP_EARTHDATA_LOGIN: "true"
@@ -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):
@@ -259,7 +258,7 @@ def L2T_STARS(
259
258
  HLS_connection = HLS2CMR(
260
259
  working_directory=working_directory,
261
260
  download_directory=HLS_download_directory,
262
- products_directory=HLS_products_directory,
261
+ # products_directory=HLS_products_directory,
263
262
  target_resolution=target_resolution,
264
263
  )
265
264
  except CMRServerUnreachable as e:
@@ -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
  )
@@ -1,6 +1,5 @@
1
- import base64
1
+ import netrc
2
2
  import hashlib
3
- import json
4
3
  import logging
5
4
  import os
6
5
  import posixpath
@@ -11,24 +10,27 @@ from datetime import date
11
10
  from fnmatch import fnmatch
12
11
  from http.cookiejar import CookieJar
13
12
  from os import makedirs, remove
14
- from os.path import abspath
15
13
  from os.path import dirname
16
14
  from os.path import exists
17
15
  from os.path import getsize
18
16
  from os.path import isdir
19
17
  from os.path import join
18
+ from os.path import abspath
19
+ from os.path import expanduser
20
20
  from time import sleep
21
21
  from typing import List, OrderedDict
22
- import netrc
22
+
23
23
  import requests
24
24
  import xmltodict
25
25
  from bs4 import BeautifulSoup
26
26
  from dateutil import parser
27
- from pycksum import cksum
27
+ from ..cksum import cksum
28
28
 
29
29
  import colored_logging as cl
30
30
 
31
- from ECOv003_exit_codes import *
31
+
32
+ class DownloadFailed(Exception):
33
+ pass
32
34
 
33
35
  CONNECTION_CLOSE = {
34
36
  "Connection": "close",
@@ -57,7 +59,7 @@ class LPDAACDataPool:
57
59
  DATE_REGEX = re.compile(r'^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$')
58
60
  DEFAULT_REMOTE = DEFAULT_REMOTE
59
61
 
60
- def __init__(self, username: str = None, password: str = None, remote: str = None, offline_ok: bool = False):
62
+ def __init__(self, username: str = None, password: str = None, remote: str = None, offline_ok: bool = True):
61
63
  if remote is None:
62
64
  remote = DEFAULT_REMOTE
63
65
 
@@ -66,15 +68,14 @@ class LPDAACDataPool:
66
68
  netrc_file = netrc.netrc()
67
69
  username, _, password = netrc_file.authenticators("urs.earthdata.nasa.gov")
68
70
  except Exception as e:
69
- logger.exception(e)
70
71
  logger.warning("netrc credentials not found for urs.earthdata.nasa.gov")
71
72
 
72
73
  if username is None or password is None:
73
74
  if not "LPDAAC_USERNAME" in os.environ or not "LPDAAC_PASSWORD" in os.environ:
74
- raise RuntimeError("Missing environment variable 'LPDAAC_USERNAME' or 'LPDAAC_PASSWORD'")
75
-
76
- username = os.environ["LPDAAC_USERNAME"]
77
- password = os.environ["LPDAAC_PASSWORD"]
75
+ logger.warning("missing environment variable 'LPDAAC_USERNAME' or 'LPDAAC_PASSWORD'")
76
+ else:
77
+ username = os.environ["LPDAAC_USERNAME"]
78
+ password = os.environ["LPDAAC_PASSWORD"]
78
79
 
79
80
  self._remote = remote
80
81
  self._username = username
@@ -86,14 +87,15 @@ class LPDAACDataPool:
86
87
 
87
88
  self._listings = {}
88
89
 
89
- try:
90
- self._authenticate()
91
- self._check_remote()
92
- except Exception as e:
93
- if self.offline_ok:
94
- logger.warning("unable to connect to LP-DAAC data pool")
95
- else:
96
- raise e
90
+ if not self.offline_ok:
91
+ try:
92
+ self._authenticate()
93
+ self._check_remote()
94
+ except Exception as e:
95
+ if self.offline_ok:
96
+ logger.warning("unable to connect to LP-DAAC data pool")
97
+ else:
98
+ raise e
97
99
 
98
100
  def _authenticate(self):
99
101
  try:
@@ -128,7 +130,7 @@ class LPDAACDataPool:
128
130
  raise ConnectionError(message)
129
131
 
130
132
  def _check_remote(self):
131
- logger.info(f"checking URL: {cl.URL(self.remote)}")
133
+ logger.debug(f"checking URL: {cl.URL(self.remote)}")
132
134
 
133
135
  try:
134
136
  response = requests.head(self.remote, headers=CONNECTION_CLOSE)
@@ -145,7 +147,7 @@ class LPDAACDataPool:
145
147
  raise LPDAACServerUnreachable(message)
146
148
 
147
149
  if status == 200:
148
- logger.info(
150
+ logger.debug(
149
151
  "remote verified with status " + cl.val(200) +
150
152
  " in " + cl.time(f"{duration:0.2f}") +
151
153
  " seconds: " + cl.URL(self.remote))
@@ -307,7 +309,7 @@ class LPDAACDataPool:
307
309
  else:
308
310
  metadata_filename = f"{download_location}.xml"
309
311
 
310
- makedirs(dirname(metadata_filename), exist_ok=True)
312
+ makedirs(abspath(dirname(expanduser(metadata_filename))), exist_ok=True)
311
313
 
312
314
  if XML_retries is None:
313
315
  XML_retries = XML_RETRIES
@@ -325,8 +327,8 @@ class LPDAACDataPool:
325
327
 
326
328
  while XML_retries > 0:
327
329
  XML_retries -= 1
328
- command = f"wget -nc -c --user {self._username} --password {self._password} -O {metadata_filename} {metadata_URL}"
329
- logger.info(command)
330
+ command = f"wget -nc -c --user {self._username} --password {self._password} -O {abspath(expanduser(metadata_filename))} {metadata_URL}"
331
+ # logger.info(command)
330
332
  os.system(command)
331
333
 
332
334
  if not exists(metadata_filename):
@@ -350,12 +352,12 @@ class LPDAACDataPool:
350
352
  continue
351
353
 
352
354
  try:
353
- with open(metadata_filename, "r") as file:
355
+ with open(abspath(expanduser(metadata_filename)), "r") as file:
354
356
  metadata = xmltodict.parse(file.read())
355
357
  except Exception as e:
356
358
  logger.warning(e)
357
359
  logger.warning(f"unable to parse metadata file: {metadata_filename}")
358
- os.remove(metadata_filename)
360
+ os.remove(abspath(expanduser(metadata_filename)))
359
361
  logger.warning(f"waiting {XML_timeout_seconds} for retry")
360
362
  sleep(XML_timeout_seconds)
361
363
  continue
@@ -372,7 +374,7 @@ class LPDAACDataPool:
372
374
 
373
375
  logger.info(
374
376
  f"metadata retrieved {checksum_type} checksum: {cl.val(remote_checksum)} size: {cl.val(remote_filesize)} URL: {cl.URL(metadata_URL)}")
375
- makedirs(dirname(filename), exist_ok=True)
377
+ makedirs(abspath(dirname(expanduser(filename))), exist_ok=True)
376
378
  logger.info(f"downloading {cl.URL(URL)} -> {cl.file(filename)}")
377
379
 
378
380
  # Use a temporary file for downloading
@@ -382,8 +384,8 @@ class LPDAACDataPool:
382
384
  download_retries -=1
383
385
 
384
386
  try:
385
- if exists(temporary_filename):
386
- temporary_filesize = self.get_local_filesize(temporary_filename)
387
+ if exists(abspath(expanduser(temporary_filename))):
388
+ temporary_filesize = self.get_local_filesize(abspath(expanduser(temporary_filename)))
387
389
 
388
390
  if temporary_filesize > remote_filesize:
389
391
  logger.warning(
@@ -391,11 +393,11 @@ class LPDAACDataPool:
391
393
  remove(temporary_filename)
392
394
 
393
395
  elif temporary_filesize == remote_filesize:
394
- local_checksum = self.get_local_checksum(temporary_filename, checksum_type=checksum_type)
396
+ local_checksum = self.get_local_checksum(abspath(expanduser(temporary_filename)), checksum_type=checksum_type)
395
397
 
396
398
  if local_checksum == remote_checksum:
397
399
  try:
398
- shutil.move(temporary_filename, filename)
400
+ shutil.move(abspath(expanduser(temporary_filename)), abspath(expanduser(filename)))
399
401
  except Exception as e:
400
402
  if exists(filename):
401
403
  logger.warning(f"unable to move temporary file: {temporary_filename}")
@@ -408,27 +410,27 @@ class LPDAACDataPool:
408
410
  else:
409
411
  logger.warning(
410
412
  f"removing corrupted file with local checksum {local_checksum} and remote checksum {remote_checksum}: {temporary_filename}")
411
- remove(temporary_filename)
413
+ remove(abspath(expanduser(temporary_filename)))
412
414
  else:
413
415
  logger.info(f"resuming incomplete download: {cl.file(temporary_filename)}")
414
416
 
415
- command = f"wget -nc -c --user {self._username} --password {self._password} -O {temporary_filename} {URL}"
416
- logger.info(command)
417
+ command = f"wget -nc -c --user {self._username} --password {self._password} -O {abspath(expanduser(temporary_filename))} {URL}"
418
+ # logger.info(command)
417
419
  os.system(command)
418
420
 
419
- if not exists(temporary_filename):
421
+ if not exists(abspath(expanduser(temporary_filename))):
420
422
  raise ConnectionError(f"unable to download URL: {URL}")
421
423
 
422
- local_filesize = self.get_local_filesize(temporary_filename)
423
- local_checksum = self.get_local_checksum(temporary_filename, checksum_type=checksum_type)
424
+ local_filesize = self.get_local_filesize(abspath(expanduser(temporary_filename)))
425
+ local_checksum = self.get_local_checksum(abspath(expanduser(temporary_filename)), checksum_type=checksum_type)
424
426
 
425
427
  if local_filesize != remote_filesize or local_checksum != remote_checksum:
426
- os.remove(temporary_filename)
428
+ os.remove(abspath(expanduser(temporary_filename)))
427
429
  raise ConnectionError(
428
430
  f"removing corrupted file with local filesize {local_filesize} remote filesize {remote_filesize} local checksum {local_checksum} remote checksum {remote_checksum}: {temporary_filename}")
429
431
 
430
432
  # Download successful, rename the temporary file to its proper name
431
- shutil.move(temporary_filename, filename)
433
+ shutil.move(abspath(expanduser(temporary_filename)), abspath(expanduser(filename)))
432
434
 
433
435
  logger.info(
434
436
  f"successful download with filesize {cl.val(local_filesize)} checksum {cl.val(local_checksum)}: {cl.file(filename)}")
@@ -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"
@@ -24,10 +24,11 @@ from modland import generate_modland_grid
24
24
 
25
25
  from ECOv003_exit_codes import *
26
26
 
27
+ from ..login import login
27
28
  from ..daterange import get_date
28
29
  from ..LPDAAC.LPDAACDataPool import RETRIES
29
30
  from .VIIRSDataPool import VIIRSGranule
30
- from .VIIRS_CMR_LOGIN import CMRServerUnreachable, VIIRS_CMR_login
31
+ from ..exceptions import *
31
32
 
32
33
  NDVI_COLORMAP = LinearSegmentedColormap.from_list(
33
34
  name="NDVI",
@@ -1095,7 +1096,7 @@ class VNP09GA:
1095
1096
 
1096
1097
  self.resampling = resampling
1097
1098
 
1098
- self._granules = pd.DataFrame({"date_UTC": {}, "tile": {}, "granule": {}})
1099
+ self._granules = pd.DataFrame(columns=["date_UTC", "tile", "granule"])
1099
1100
 
1100
1101
  if working_directory is None:
1101
1102
  working_directory = self.DEFAULT_WORKING_DIRECTORY
@@ -1122,7 +1123,7 @@ class VNP09GA:
1122
1123
  self.products_directory = products_directory
1123
1124
  self.mosaic_directory = mosaic_directory
1124
1125
 
1125
- self.auth = VIIRS_CMR_login()
1126
+ self.auth = login()
1126
1127
 
1127
1128
  def add_granules(self, granules: List[earthaccess.search.DataGranule]):
1128
1129
  data = pd.DataFrame([
@@ -1232,7 +1233,7 @@ class VNP09GA:
1232
1233
  if "date_UTC" not in self._granules.columns:
1233
1234
  raise ValueError(f"date_UTC column not in granules table")
1234
1235
 
1235
- 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)]
1236
1237
  if len(subset) > 0:
1237
1238
  return subset.iloc[0].granule
1238
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"))
@@ -1,3 +1,3 @@
1
1
  from .version import __version__, __author__
2
- from .ECOv003_L2T_STARS import *
2
+ from .main import *
3
3
  from .ECOv003_DL import *
@@ -0,0 +1,66 @@
1
+ """
2
+ Pure Python implementation of POSIX cksum algorithm.
3
+
4
+ This module provides a replacement for the pycksum package that is compatible
5
+ with Python 3.12 and later versions.
6
+ """
7
+
8
+
9
+ def cksum(data_or_file):
10
+ """
11
+ Calculate POSIX cksum checksum for data or file-like object.
12
+
13
+ Args:
14
+ data_or_file: Either bytes data or a file-like object opened in binary mode
15
+
16
+ Returns:
17
+ int: The POSIX cksum checksum value
18
+ """
19
+ # Handle file-like objects
20
+ if hasattr(data_or_file, 'read'):
21
+ data = data_or_file.read()
22
+ else:
23
+ data = data_or_file
24
+
25
+ # Ensure we have bytes
26
+ if isinstance(data, str):
27
+ data = data.encode('utf-8')
28
+
29
+ # Initialize CRC with 0
30
+ crc = 0
31
+
32
+ # Process each byte of data
33
+ for byte in data:
34
+ # XOR the byte with the current CRC (shifted left 8 bits)
35
+ crc ^= byte << 24
36
+
37
+ # Process 8 bits
38
+ for _ in range(8):
39
+ if crc & 0x80000000: # If MSB is set
40
+ crc = (crc << 1) ^ 0x04c11db7 # CRC-32 polynomial
41
+ else:
42
+ crc = crc << 1
43
+ crc &= 0xffffffff # Keep it 32-bit
44
+
45
+ # Append the length in bytes as a big-endian value
46
+ length = len(data)
47
+ length_bytes = []
48
+ while length > 0:
49
+ length_bytes.insert(0, length & 0xff)
50
+ length >>= 8
51
+
52
+ # Process the length bytes
53
+ for byte in length_bytes:
54
+ crc ^= byte << 24
55
+ for _ in range(8):
56
+ if crc & 0x80000000:
57
+ crc = (crc << 1) ^ 0x04c11db7
58
+ else:
59
+ crc = crc << 1
60
+ crc &= 0xffffffff
61
+
62
+ # Final XOR and return as signed 32-bit integer equivalent
63
+ result = crc ^ 0xffffffff
64
+
65
+ # Convert to match expected return type (unsigned 32-bit integer)
66
+ return result
@@ -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,2 @@
1
+ class CMRServerUnreachable(Exception):
2
+ pass