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.
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/.github/workflows/ci.yml +6 -1
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/L2T_STARS.py +9 -24
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/LPDAACDataPool.py +42 -40
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/Project.toml +0 -4
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP09GA.py +5 -4
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/VNP43NRT.py +9 -4
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/__init__.py +1 -1
- ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/cksum.py +66 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/constants.py +1 -0
- ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/exceptions.py +2 -0
- ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/generate_STARS_inputs.py +233 -0
- ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/generate_downsampled_filename.py +20 -0
- 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
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/load_prior.py +4 -4
- ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS/login.py +61 -0
- 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
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_ECOSTRESS_data_fusion_distributed_bias.jl +19 -26
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_STARS_product.py +26 -40
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/process_julia_data_fusion.py +10 -8
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/PKG-INFO +1 -2
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/SOURCES.txt +7 -9
- ecov003_l2t_stars-1.4.0/ECOv003_L2T_STARS.egg-info/entry_points.txt +3 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/requires.txt +0 -1
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/PKG-INFO +1 -2
- ecov003_l2t_stars-1.4.0/makefile +90 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/pyproject.toml +2 -3
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/tests/test_import_dependencies.py +0 -1
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/VIIRS/VIIRS_CMR_LOGIN.py +0 -36
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_NDVI_coarse_directory.py +0 -21
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_NDVI_fine_directory.py +0 -14
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_STARS_inputs.py +0 -231
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_albedo_coarse_directory.py +0 -18
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/generate_albedo_fine_directory.py +0 -17
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS/install_STARS_jl.py +0 -43
- ecov003_l2t_stars-1.2.0/ECOv003_L2T_STARS.egg-info/entry_points.txt +0 -3
- ecov003_l2t_stars-1.2.0/makefile +0 -66
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/.github/workflows/python-publish.yml +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/.gitignore +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/Dockerfile +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOSTRESS Granule Download Bias.ipynb +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOSTRESS Granule Download.ipynb +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/BRDF.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/SZA.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/statistical_radiative_transport.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/BRDF/version.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_DL.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_DL.xml +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/ECOv003_L2T_STARS.xml +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/L2TSTARSConfig.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/version.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/Manifest.toml +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VIIRSDataPool.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VIIRSDownloader.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP43IA4.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/VNP43MA3.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VIIRS/version.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/process_VNP43NRT.jl +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT/version.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/Manifest.toml +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/Project.toml +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.jl +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/src/VNP43NRT.jl +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/VNP43NRT_jl/src/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/calibrate_fine_to_coarse.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/daterange/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/daterange/daterange.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_L2T_STARS_runconfig.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_NDVI_coarse_image.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_NDVI_fine_image.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_albedo_coarse_image.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_albedo_fine_image.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_filename.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_input_staging_directory.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_model_state_tile_date_directory.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/generate_output_directory.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/prior.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/retrieve_STARS_sources.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/runconfig.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/timer/__init__.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/timer/timer.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/version.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/version.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/dependency_links.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS.egg-info/top_level.txt +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/LICENSE +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/README.md +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/STARS_memory_profile.jpeg +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/demo.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/example_L2T_STARS_with_download.py +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/mprofile_20241202193217.dat +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/mprofile_20241203112611.dat +0 -0
- {ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/setup.cfg +0 -0
- /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
|
-
|
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
|
-
|
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
|
)
|
{ecov003_l2t_stars-1.2.0 → ecov003_l2t_stars-1.4.0}/ECOv003_L2T_STARS/LPDAAC/LPDAACDataPool.py
RENAMED
@@ -1,6 +1,5 @@
|
|
1
|
-
import
|
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
|
-
|
22
|
+
|
23
23
|
import requests
|
24
24
|
import xmltodict
|
25
25
|
from bs4 import BeautifulSoup
|
26
26
|
from dateutil import parser
|
27
|
-
from
|
27
|
+
from ..cksum import cksum
|
28
28
|
|
29
29
|
import colored_logging as cl
|
30
30
|
|
31
|
-
|
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 =
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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.
|
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.
|
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
|
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(
|
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 =
|
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
|
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
|
-
|
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"))
|
@@ -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
|