ECOv003-L2T-STARS 1.0.1__py3-none-any.whl → 1.2.0__py3-none-any.whl

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 (75) hide show
  1. ECOv003_L2T_STARS/BRDF/BRDF.py +57 -0
  2. ECOv003_L2T_STARS/BRDF/SZA.py +65 -0
  3. ECOv003_L2T_STARS/BRDF/__init__.py +1 -0
  4. ECOv003_L2T_STARS/BRDF/statistical_radiative_transport.txt +90 -0
  5. ECOv003_L2T_STARS/BRDF/version.txt +1 -0
  6. ECOv003_L2T_STARS/ECOv003_DL.py +527 -0
  7. ECOv003_L2T_STARS/ECOv003_DL.xml +47 -0
  8. ECOv003_L2T_STARS/ECOv003_L2T_STARS.py +169 -0
  9. ECOv003_L2T_STARS/ECOv003_L2T_STARS.xml +47 -0
  10. ECOv003_L2T_STARS/L2TSTARSConfig.py +190 -0
  11. ECOv003_L2T_STARS/L2T_STARS.py +503 -0
  12. ECOv003_L2T_STARS/LPDAAC/LPDAACDataPool.py +444 -0
  13. ECOv003_L2T_STARS/LPDAAC/__init__.py +9 -0
  14. ECOv003_L2T_STARS/LPDAAC/version.txt +1 -0
  15. ECOv003_L2T_STARS/Manifest.toml +2332 -0
  16. ECOv003_L2T_STARS/Project.toml +14 -0
  17. ECOv003_L2T_STARS/VIIRS/VIIRSDataPool.py +294 -0
  18. ECOv003_L2T_STARS/VIIRS/VIIRSDownloader.py +26 -0
  19. ECOv003_L2T_STARS/VIIRS/VIIRS_CMR_LOGIN.py +36 -0
  20. ECOv003_L2T_STARS/VIIRS/VNP09GA.py +1278 -0
  21. ECOv003_L2T_STARS/VIIRS/VNP43IA4.py +288 -0
  22. ECOv003_L2T_STARS/VIIRS/VNP43MA3.py +323 -0
  23. ECOv003_L2T_STARS/VIIRS/__init__.py +9 -0
  24. ECOv003_L2T_STARS/VIIRS/version.txt +1 -0
  25. ECOv003_L2T_STARS/VNP43NRT/VNP43NRT.py +863 -0
  26. ECOv003_L2T_STARS/VNP43NRT/__init__.py +1 -0
  27. ECOv003_L2T_STARS/VNP43NRT/process_VNP43NRT.jl +169 -0
  28. ECOv003_L2T_STARS/VNP43NRT/version.txt +1 -0
  29. ECOv003_L2T_STARS/VNP43NRT_jl/Manifest.toml +995 -0
  30. ECOv003_L2T_STARS/VNP43NRT_jl/Project.toml +15 -0
  31. ECOv003_L2T_STARS/VNP43NRT_jl/__init__.py +0 -0
  32. ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.jl +25 -0
  33. ECOv003_L2T_STARS/VNP43NRT_jl/instantiate.py +13 -0
  34. ECOv003_L2T_STARS/VNP43NRT_jl/src/VNP43NRT.jl +411 -0
  35. ECOv003_L2T_STARS/VNP43NRT_jl/src/__init__.py +0 -0
  36. ECOv003_L2T_STARS/__init__.py +3 -0
  37. ECOv003_L2T_STARS/calibrate_fine_to_coarse.py +60 -0
  38. ECOv003_L2T_STARS/constants.py +38 -0
  39. ECOv003_L2T_STARS/daterange/__init__.py +1 -0
  40. ECOv003_L2T_STARS/daterange/daterange.py +35 -0
  41. ECOv003_L2T_STARS/generate_L2T_STARS_runconfig.py +249 -0
  42. ECOv003_L2T_STARS/generate_NDVI_coarse_directory.py +21 -0
  43. ECOv003_L2T_STARS/generate_NDVI_coarse_image.py +30 -0
  44. ECOv003_L2T_STARS/generate_NDVI_fine_directory.py +14 -0
  45. ECOv003_L2T_STARS/generate_NDVI_fine_image.py +28 -0
  46. ECOv003_L2T_STARS/generate_STARS_inputs.py +231 -0
  47. ECOv003_L2T_STARS/generate_albedo_coarse_directory.py +18 -0
  48. ECOv003_L2T_STARS/generate_albedo_coarse_image.py +30 -0
  49. ECOv003_L2T_STARS/generate_albedo_fine_directory.py +17 -0
  50. ECOv003_L2T_STARS/generate_albedo_fine_image.py +30 -0
  51. ECOv003_L2T_STARS/generate_filename.py +37 -0
  52. ECOv003_L2T_STARS/generate_input_staging_directory.py +23 -0
  53. ECOv003_L2T_STARS/generate_model_state_tile_date_directory.py +28 -0
  54. ECOv003_L2T_STARS/generate_output_directory.py +28 -0
  55. ECOv003_L2T_STARS/install_STARS_jl.py +43 -0
  56. ECOv003_L2T_STARS/instantiate_STARS_jl.py +38 -0
  57. ECOv003_L2T_STARS/load_prior.py +250 -0
  58. ECOv003_L2T_STARS/prior.py +56 -0
  59. ECOv003_L2T_STARS/process_ECOSTRESS_data_fusion_distributed_bias.jl +420 -0
  60. ECOv003_L2T_STARS/process_STARS_product.py +507 -0
  61. ECOv003_L2T_STARS/process_julia_data_fusion.py +110 -0
  62. ECOv003_L2T_STARS/retrieve_STARS_sources.py +101 -0
  63. ECOv003_L2T_STARS/runconfig.py +70 -0
  64. ECOv003_L2T_STARS/timer/__init__.py +1 -0
  65. ECOv003_L2T_STARS/timer/timer.py +77 -0
  66. ECOv003_L2T_STARS/version.py +8 -0
  67. ECOv003_L2T_STARS/version.txt +1 -0
  68. {ECOv003_L2T_STARS-1.0.1.dist-info → ecov003_l2t_stars-1.2.0.dist-info}/METADATA +31 -24
  69. ecov003_l2t_stars-1.2.0.dist-info/RECORD +73 -0
  70. {ECOv003_L2T_STARS-1.0.1.dist-info → ecov003_l2t_stars-1.2.0.dist-info}/WHEEL +1 -1
  71. ecov003_l2t_stars-1.2.0.dist-info/entry_points.txt +3 -0
  72. ecov003_l2t_stars-1.2.0.dist-info/top_level.txt +1 -0
  73. ECOv003_L2T_STARS-1.0.1.dist-info/RECORD +0 -5
  74. ECOv003_L2T_STARS-1.0.1.dist-info/top_level.txt +0 -1
  75. {ECOv003_L2T_STARS-1.0.1.dist-info → ecov003_l2t_stars-1.2.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,37 @@
1
+ from typing import Union
2
+ from os import makedirs
3
+ from os.path import join, dirname, abspath
4
+ from datetime import date
5
+
6
+ from dateutil import parser
7
+
8
+ def generate_filename(
9
+ directory: str, variable: str, date_UTC: Union[date, str], tile: str, cell_size: int
10
+ ) -> str:
11
+ """
12
+ Generates a standardized filename for a raster product and ensures its directory exists.
13
+
14
+ The filename format is STARS_{variable}_{YYYY-MM-DD}_{tile}_{cell_size}m.tif.
15
+
16
+ Args:
17
+ directory (str): The base directory where the file will be saved.
18
+ variable (str): The name of the variable (e.g., "NDVI", "albedo").
19
+ date_UTC (Union[date, str]): The UTC date of the data. Can be a date object or a string.
20
+ tile (str): The HLS tile ID (e.g., 'H09V05').
21
+ cell_size (int): The spatial resolution in meters (e.g., 70, 490, 980).
22
+
23
+ Returns:
24
+ str: The full, standardized path to the generated filename.
25
+ """
26
+ if isinstance(date_UTC, str):
27
+ date_UTC = parser.parse(date_UTC).date()
28
+
29
+ variable = str(variable)
30
+ timestamp = date_UTC.strftime("%Y-%m-%d")
31
+ tile = str(tile)
32
+ cell_size = int(cell_size)
33
+ filename = join(directory, f"STARS_{variable}_{timestamp}_{tile}_{cell_size}m.tif")
34
+ # Ensure the directory structure for the file exists
35
+ makedirs(dirname(filename), exist_ok=True)
36
+
37
+ return filename
@@ -0,0 +1,23 @@
1
+ from os import makedirs
2
+ from os.path import join
3
+
4
+ def generate_input_staging_directory(
5
+ input_staging_directory: str,
6
+ tile: str,
7
+ prefix: str) -> str:
8
+ """
9
+ Generates a path for an input staging directory and ensures it exists.
10
+
11
+ This is used to organize temporary input files for the Julia processing.
12
+
13
+ Args:
14
+ input_staging_directory (str): The base input staging directory.
15
+ tile (str): The HLS tile ID.
16
+ prefix (str): A prefix for the sub-directory name (e.g., "NDVI_coarse").
17
+
18
+ Returns:
19
+ str: The full path to the created or existing staging directory.
20
+ """
21
+ directory = join(input_staging_directory, f"{prefix}_{tile}")
22
+ makedirs(directory, exist_ok=True) # Create directory if it doesn't exist
23
+ return directory
@@ -0,0 +1,28 @@
1
+ from typing import Union
2
+ from datetime import date
3
+ from os import makedirs
4
+ from os.path import join
5
+
6
+ from dateutil import parser
7
+
8
+ def generate_model_state_tile_date_directory(
9
+ model_directory: str, tile: str, date_UTC: Union[date, str]
10
+ ) -> str:
11
+ """
12
+ Generates a directory for storing model state files (e.g., priors, posteriors)
13
+ organized by tile and date, and ensures it exists.
14
+
15
+ Args:
16
+ model_directory (str): The base directory for model state files.
17
+ tile (str): The HLS tile ID.
18
+ date_UTC (Union[date, str]): The UTC date for the model state.
19
+
20
+ Returns:
21
+ str: The full path to the created or existing model state directory.
22
+ """
23
+ if isinstance(date_UTC, str):
24
+ date_UTC = parser.parse(date_UTC).date()
25
+
26
+ directory = join(model_directory, tile, f"{date_UTC:%Y-%m-%d}")
27
+ makedirs(directory, exist_ok=True) # Create directory if it doesn't exist
28
+ return directory
@@ -0,0 +1,28 @@
1
+ from typing import Union
2
+ from datetime import date
3
+ from os import makedirs
4
+ from os.path import join
5
+
6
+ from dateutil import parser
7
+
8
+ def generate_output_directory(
9
+ working_directory: str,
10
+ date_UTC: Union[date, str],
11
+ tile: str) -> str:
12
+ """
13
+ Generates a dated output directory for Julia model results and ensures it exists.
14
+
15
+ Args:
16
+ working_directory (str): The main working directory.
17
+ date_UTC (Union[date, str]): The UTC date for the output.
18
+ tile (str): The HLS tile ID.
19
+
20
+ Returns:
21
+ str: The full path to the created or existing output directory.
22
+ """
23
+ if isinstance(date_UTC, str):
24
+ date_UTC = parser.parse(date_UTC).date()
25
+
26
+ directory = join(working_directory, f"julia_output_{date_UTC:%y.%m.%d}_{tile}")
27
+ makedirs(directory, exist_ok=True) # Create directory if it doesn't exist
28
+ return directory
@@ -0,0 +1,43 @@
1
+ import subprocess
2
+ import logging
3
+
4
+ logger = logging.getLogger(__name__)
5
+
6
+ def install_STARS_jl(
7
+ github_URL: str = "https://github.com/STARS-Data-Fusion/STARS.jl",
8
+ environment_name: str = "@ECOv003-L2T-STARS") -> subprocess.CompletedProcess:
9
+ """
10
+ Installs the STARS.jl Julia package from GitHub into a specified Julia environment.
11
+
12
+ This function executes a Julia command to activate a given environment and
13
+ then develops (installs in editable mode) the STARS.jl package from its
14
+ GitHub repository.
15
+
16
+ Args:
17
+ github_URL (str, optional): The URL of the GitHub repository containing STARS.jl.
18
+ Defaults to "https://github.com/STARS-Data-Fusion/STARS.jl".
19
+ environment_name (str, optional): The name of the Julia environment to install
20
+ the package into. Defaults to "@ECOv003-L2T-STARS".
21
+
22
+ Returns:
23
+ subprocess.CompletedProcess: An object containing information about the
24
+ execution of the Julia command (return code, stdout, stderr).
25
+ """
26
+ # Julia command to activate an environment and then add/develop a package from URL
27
+ julia_command = [
28
+ "julia",
29
+ "-e",
30
+ f'using Pkg; Pkg.activate("{environment_name}"); Pkg.develop(url="{github_URL}")',
31
+ ]
32
+
33
+ # Execute the Julia command as a subprocess
34
+ result = subprocess.run(julia_command, capture_output=True, text=True, check=False)
35
+
36
+ if result.returncode == 0:
37
+ logger.info(
38
+ f"STARS.jl installed successfully in environment '{environment_name}'!"
39
+ )
40
+ else:
41
+ logger.error("Error installing STARS.jl:")
42
+ logger.error(result.stderr)
43
+ return result
@@ -0,0 +1,38 @@
1
+ import subprocess
2
+ import logging
3
+
4
+ logger = logging.getLogger(__name__)
5
+
6
+ def instantiate_STARS_jl(package_location: str) -> subprocess.CompletedProcess:
7
+ """
8
+ Activates a Julia project at a given location and instantiates its dependencies.
9
+
10
+ This is necessary to ensure all required Julia packages for STARS.jl are
11
+ downloaded and ready for use within the specified project environment.
12
+
13
+ Args:
14
+ package_location (str): The directory of the Julia package (where Project.toml is located)
15
+ to activate and instantiate.
16
+
17
+ Returns:
18
+ subprocess.CompletedProcess: An object containing information about the
19
+ execution of the Julia command (return code, stdout, stderr).
20
+ """
21
+ # Julia command to activate a specific package location and then instantiate its dependencies
22
+ julia_command = [
23
+ "julia",
24
+ "-e",
25
+ f'using Pkg; Pkg.activate("{package_location}"); Pkg.instantiate()',
26
+ ]
27
+
28
+ # Execute the Julia command as a subprocess
29
+ result = subprocess.run(julia_command, capture_output=True, text=True, check=False)
30
+
31
+ if result.returncode == 0:
32
+ logger.info(
33
+ f"STARS.jl instantiated successfully in directory '{package_location}'!"
34
+ )
35
+ else:
36
+ logger.error("Error instantiating STARS.jl:")
37
+ logger.error(result.stderr)
38
+ return result
@@ -0,0 +1,250 @@
1
+ from os.path import exists
2
+ import logging
3
+
4
+ import colored_logging as cl
5
+
6
+ from ECOv003_granules import L2TSTARS
7
+
8
+ from .prior import Prior
9
+ from .generate_filename import generate_filename
10
+ from .generate_model_state_tile_date_directory import generate_model_state_tile_date_directory
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ def load_prior(
15
+ tile: str,
16
+ target_resolution: int,
17
+ model_directory: str,
18
+ L2T_STARS_prior_filename: str) -> Prior:
19
+ """
20
+ Loads a prior L2T_STARS product if available and extracts its components.
21
+
22
+ This function attempts to load a previously generated L2T_STARS product
23
+ to use its NDVI and albedo mean, uncertainty, and bias as prior information
24
+ for the current data fusion run.
25
+
26
+ Args:
27
+ tile (str): The HLS tile ID.
28
+ target_resolution (int): The target resolution of the L2T_STARS product.
29
+ model_directory (str): The base directory for model state files.
30
+ L2T_STARS_prior_filename (str): The filename of the prior L2T_STARS product (zip file).
31
+
32
+ Returns:
33
+ Prior: A Prior object containing paths to the prior data components
34
+ and a flag indicating if a valid prior was loaded.
35
+ """
36
+ using_prior = False
37
+ prior_date_UTC = None
38
+ prior_NDVI_filename = None
39
+ prior_NDVI_UQ_filename = None
40
+ prior_NDVI_bias_filename = None
41
+ prior_NDVI_bias_UQ_filename = None
42
+ prior_albedo_filename = None
43
+ prior_albedo_UQ_filename = None
44
+ prior_albedo_bias_filename = None
45
+ prior_albedo_bias_UQ_filename = None
46
+
47
+ # Check if a prior L2T_STARS product is specified and exists
48
+ if L2T_STARS_prior_filename is not None and exists(L2T_STARS_prior_filename):
49
+ logger.info(f"Loading prior L2T STARS product: {L2T_STARS_prior_filename}")
50
+ try:
51
+ # Initialize L2TSTARS object from the prior product
52
+ L2T_STARS_prior_granule = L2TSTARS(L2T_STARS_prior_filename)
53
+ prior_date_UTC = L2T_STARS_prior_granule.date_UTC
54
+ logger.info(f"Prior date: {cl.time(prior_date_UTC)}")
55
+
56
+ # Extract NDVI and albedo mean and uncertainty rasters
57
+ NDVI_prior_mean = L2T_STARS_prior_granule.NDVI
58
+ NDVI_prior_UQ = L2T_STARS_prior_granule.NDVI_UQ
59
+ albedo_prior_mean = L2T_STARS_prior_granule.albedo
60
+ albedo_prior_UQ = L2T_STARS_prior_granule.albedo_UQ
61
+
62
+ # Define the directory for storing prior model state files
63
+ prior_tile_date_directory = generate_model_state_tile_date_directory(
64
+ model_directory=model_directory, tile=tile, date_UTC=prior_date_UTC
65
+ )
66
+
67
+ # Generate and save filenames for all prior components
68
+ prior_NDVI_filename = generate_filename(
69
+ directory=prior_tile_date_directory,
70
+ variable="NDVI",
71
+ date_UTC=prior_date_UTC,
72
+ tile=tile,
73
+ cell_size=target_resolution,
74
+ )
75
+ NDVI_prior_mean.to_geotiff(prior_NDVI_filename)
76
+
77
+ prior_NDVI_UQ_filename = generate_filename(
78
+ directory=prior_tile_date_directory,
79
+ variable="NDVI.UQ",
80
+ date_UTC=prior_date_UTC,
81
+ tile=tile,
82
+ cell_size=target_resolution,
83
+ )
84
+ NDVI_prior_UQ.to_geotiff(prior_NDVI_UQ_filename)
85
+
86
+ # Note: Prior bias files might not always exist in older products.
87
+ # Assuming they could be extracted from L2T_STARS_prior_granule if present.
88
+ # For simplicity, these are placeholders and would need proper extraction logic
89
+ # from the L2TSTARS granule if they are actual components.
90
+ # For now, we set them based on `generate_filename` only if a bias layer is retrieved.
91
+ # If the bias layers are not explicitly part of `L2TSTARS` object, these will be None
92
+ # unless written explicitly during prior creation.
93
+ prior_NDVI_bias_filename = generate_filename(
94
+ directory=prior_tile_date_directory,
95
+ variable="NDVI.bias",
96
+ date_UTC=prior_date_UTC,
97
+ tile=tile,
98
+ cell_size=target_resolution,
99
+ )
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:
102
+ L2T_STARS_prior_granule.NDVI_bias.to_geotiff(prior_NDVI_bias_filename)
103
+ else:
104
+ prior_NDVI_bias_filename = None # Set to None if not available
105
+
106
+ prior_NDVI_bias_UQ_filename = generate_filename(
107
+ directory=prior_tile_date_directory,
108
+ variable="NDVI.bias.UQ",
109
+ date_UTC=prior_date_UTC,
110
+ tile=tile,
111
+ cell_size=target_resolution,
112
+ )
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:
115
+ L2T_STARS_prior_granule.NDVI_bias_UQ.to_geotiff(prior_NDVI_bias_UQ_filename)
116
+ else:
117
+ prior_NDVI_bias_UQ_filename = None # Set to None if not available
118
+
119
+
120
+ prior_albedo_filename = generate_filename(
121
+ directory=prior_tile_date_directory,
122
+ variable="albedo",
123
+ date_UTC=prior_date_UTC,
124
+ tile=tile,
125
+ cell_size=target_resolution,
126
+ )
127
+ albedo_prior_mean.to_geotiff(prior_albedo_filename)
128
+
129
+ prior_albedo_UQ_filename = generate_filename(
130
+ directory=prior_tile_date_directory,
131
+ variable="albedo.UQ",
132
+ date_UTC=prior_date_UTC,
133
+ tile=tile,
134
+ cell_size=target_resolution,
135
+ )
136
+ albedo_prior_UQ.to_geotiff(prior_albedo_UQ_filename)
137
+
138
+ prior_albedo_bias_filename = generate_filename(
139
+ directory=prior_tile_date_directory,
140
+ variable="albedo.bias",
141
+ date_UTC=prior_date_UTC,
142
+ tile=tile,
143
+ cell_size=target_resolution,
144
+ )
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:
147
+ L2T_STARS_prior_granule.albedo_bias.to_geotiff(prior_albedo_bias_filename)
148
+ else:
149
+ prior_albedo_bias_filename = None # Set to None if not available
150
+
151
+ prior_albedo_bias_UQ_filename = generate_filename(
152
+ directory=prior_tile_date_directory,
153
+ variable="albedo.bias.UQ",
154
+ date_UTC=prior_date_UTC,
155
+ tile=tile,
156
+ cell_size=target_resolution,
157
+ )
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:
160
+ L2T_STARS_prior_granule.albedo_bias_UQ.to_geotiff(prior_albedo_bias_UQ_filename)
161
+ else:
162
+ prior_albedo_bias_UQ_filename = None # Set to None if not available
163
+
164
+
165
+ using_prior = True # Mark that a prior was successfully loaded
166
+ except Exception as e:
167
+ logger.warning(f"Could not load prior L2T STARS product: {L2T_STARS_prior_filename}. Reason: {e}")
168
+ using_prior = False # Ensure using_prior is False if loading fails
169
+
170
+ # Verify that all expected prior files exist, otherwise disable using_prior
171
+ # This ensures a partial prior (e.g., only NDVI but not albedo) isn't used
172
+ if prior_NDVI_filename is not None and exists(prior_NDVI_filename):
173
+ logger.info(f"Prior NDVI ready: {prior_NDVI_filename}")
174
+ else:
175
+ logger.info(f"Prior NDVI not found: {prior_NDVI_filename}")
176
+ using_prior = False
177
+
178
+ if prior_NDVI_UQ_filename is not None and exists(prior_NDVI_UQ_filename):
179
+ logger.info(f"Prior NDVI UQ ready: {prior_NDVI_UQ_filename}")
180
+ else:
181
+ logger.info(f"Prior NDVI UQ not found: {prior_NDVI_UQ_filename}")
182
+ using_prior = False
183
+
184
+ if prior_NDVI_bias_filename is not None and exists(prior_NDVI_bias_filename):
185
+ logger.info(f"Prior NDVI bias ready: {prior_NDVI_bias_filename}")
186
+ else:
187
+ logger.info(f"Prior NDVI bias not found: {prior_NDVI_bias_filename}")
188
+ using_prior = False
189
+
190
+ if prior_NDVI_bias_UQ_filename is not None and exists(prior_NDVI_bias_UQ_filename):
191
+ logger.info(f"Prior NDVI bias UQ ready: {prior_NDVI_bias_UQ_filename}")
192
+ else:
193
+ logger.info(f"Prior NDVI bias UQ not found: {prior_NDVI_bias_UQ_filename}")
194
+ using_prior = False
195
+
196
+ if prior_albedo_filename is not None and exists(prior_albedo_filename):
197
+ logger.info(f"Prior albedo ready: {prior_albedo_filename}")
198
+ else:
199
+ logger.info(f"Prior albedo not found: {prior_albedo_filename}")
200
+ using_prior = False
201
+
202
+ if prior_albedo_UQ_filename is not None and exists(prior_albedo_UQ_filename):
203
+ logger.info(f"Prior albedo UQ ready: {prior_albedo_UQ_filename}")
204
+ else:
205
+ logger.info(f"Prior albedo UQ not found: {prior_albedo_UQ_filename}")
206
+ using_prior = False
207
+
208
+ if prior_albedo_bias_filename is not None and exists(prior_albedo_bias_filename):
209
+ logger.info(f"Prior albedo bias ready: {prior_albedo_bias_filename}")
210
+ else:
211
+ logger.info(f"Prior albedo bias not found: {prior_albedo_bias_filename}")
212
+ using_prior = False
213
+
214
+ if prior_albedo_bias_UQ_filename is not None and exists(
215
+ prior_albedo_bias_UQ_filename
216
+ ):
217
+ logger.info(f"Prior albedo bias UQ ready: {prior_albedo_bias_UQ_filename}")
218
+ else:
219
+ logger.info(f"Prior albedo bias UQ not found: {prior_albedo_bias_UQ_filename}")
220
+ using_prior = False
221
+
222
+ # Final check: if any of the critical prior files are missing, do not use prior
223
+ if not all([prior_NDVI_filename, prior_NDVI_UQ_filename, prior_albedo_filename, prior_albedo_UQ_filename]):
224
+ logger.warning("One or more required prior (mean/UQ) files are missing. Prior will not be used.")
225
+ using_prior = False
226
+ prior_NDVI_filename = None
227
+ prior_NDVI_UQ_filename = None
228
+ prior_albedo_filename = None
229
+ prior_albedo_UQ_filename = None
230
+
231
+ # FIXME where are `prior_NDVI_flag_filename` and `prior_albedo_flag_filename` defined?
232
+
233
+ # Create and return the Prior object
234
+ prior = Prior(
235
+ using_prior=using_prior,
236
+ prior_date_UTC=prior_date_UTC,
237
+ L2T_STARS_prior_filename=L2T_STARS_prior_filename,
238
+ prior_NDVI_filename=prior_NDVI_filename,
239
+ prior_NDVI_UQ_filename=prior_NDVI_UQ_filename,
240
+ # prior_NDVI_flag_filename=prior_NDVI_flag_filename,
241
+ prior_NDVI_bias_filename=prior_NDVI_bias_filename,
242
+ prior_NDVI_bias_UQ_filename=prior_NDVI_bias_UQ_filename,
243
+ prior_albedo_filename=prior_albedo_filename,
244
+ prior_albedo_UQ_filename=prior_albedo_UQ_filename,
245
+ # prior_albedo_flag_filename=prior_albedo_flag_filename,
246
+ prior_albedo_bias_filename=prior_albedo_bias_filename,
247
+ prior_albedo_bias_UQ_filename=prior_albedo_bias_UQ_filename,
248
+ )
249
+
250
+ return prior
@@ -0,0 +1,56 @@
1
+ from datetime import date
2
+
3
+ class Prior:
4
+ """
5
+ A data class to encapsulate information about a prior L2T_STARS product.
6
+
7
+ This class holds filenames and flags related to the use of a previous
8
+ STARS product as a 'prior' in the data fusion process. This can help
9
+ to constrain the solution and improve accuracy, especially when
10
+ observations for the current date are sparse.
11
+
12
+ Attributes:
13
+ using_prior (bool): True if a prior product is being used, False otherwise.
14
+ prior_date_UTC (date): The UTC date of the prior product.
15
+ L2T_STARS_prior_filename (str): Path to the prior L2T_STARS zip file.
16
+ prior_NDVI_filename (str): Path to the prior NDVI mean file.
17
+ prior_NDVI_UQ_filename (str): Path to the prior NDVI uncertainty (UQ) file.
18
+ prior_NDVI_flag_filename (str): Path to the prior NDVI flag file.
19
+ prior_NDVI_bias_filename (str): Path to the prior NDVI bias file.
20
+ prior_NDVI_bias_UQ_filename (str): Path to the prior NDVI bias uncertainty file.
21
+ prior_albedo_filename (str): Path to the prior albedo mean file.
22
+ prior_albedo_UQ_filename (str): Path to the prior albedo uncertainty (UQ) file.
23
+ prior_albedo_flag_filename (str): Path to the prior albedo flag file.
24
+ prior_albedo_bias_filename (str): Path to the prior albedo bias file.
25
+ prior_albedo_bias_UQ_filename (str): Path to the prior albedo bias uncertainty file.
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ using_prior: bool = False,
31
+ prior_date_UTC: date = None,
32
+ L2T_STARS_prior_filename: str = None,
33
+ prior_NDVI_filename: str = None,
34
+ prior_NDVI_UQ_filename: str = None,
35
+ prior_NDVI_flag_filename: str = None,
36
+ prior_NDVI_bias_filename: str = None,
37
+ prior_NDVI_bias_UQ_filename: str = None,
38
+ prior_albedo_filename: str = None,
39
+ prior_albedo_UQ_filename: str = None,
40
+ prior_albedo_flag_filename: str = None,
41
+ prior_albedo_bias_filename: str = None,
42
+ prior_albedo_bias_UQ_filename: str = None,
43
+ ):
44
+ self.using_prior = using_prior
45
+ self.prior_date_UTC = prior_date_UTC
46
+ self.L2T_STARS_prior_filename = L2T_STARS_prior_filename
47
+ self.prior_NDVI_filename = prior_NDVI_filename
48
+ self.prior_NDVI_UQ_filename = prior_NDVI_UQ_filename
49
+ self.prior_NDVI_flag_filename = prior_NDVI_flag_filename
50
+ self.prior_NDVI_bias_filename = prior_NDVI_bias_filename
51
+ self.prior_NDVI_bias_UQ_filename = prior_NDVI_bias_UQ_filename
52
+ self.prior_albedo_filename = prior_albedo_filename
53
+ self.prior_albedo_UQ_filename = prior_albedo_UQ_filename
54
+ self.prior_albedo_flag_filename = prior_albedo_flag_filename
55
+ self.prior_albedo_bias_filename = prior_albedo_bias_filename
56
+ self.prior_albedo_bias_UQ_filename = prior_albedo_bias_UQ_filename