ECOv003-L2T-STARS 1.0.0__py3-none-any.whl → 1.1.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 +162 -0
  9. ECOv003_L2T_STARS/ECOv003_L2T_STARS.xml +47 -0
  10. ECOv003_L2T_STARS/L2TSTARSConfig.py +188 -0
  11. ECOv003_L2T_STARS/L2T_STARS.py +489 -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 +1277 -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 +248 -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.0.dist-info → ecov003_l2t_stars-1.1.0.dist-info}/METADATA +30 -23
  69. ecov003_l2t_stars-1.1.0.dist-info/RECORD +73 -0
  70. {ECOv003_L2T_STARS-1.0.0.dist-info → ecov003_l2t_stars-1.1.0.dist-info}/WHEEL +1 -1
  71. ecov003_l2t_stars-1.1.0.dist-info/entry_points.txt +3 -0
  72. ecov003_l2t_stars-1.1.0.dist-info/top_level.txt +1 -0
  73. ECOv003_L2T_STARS-1.0.0.dist-info/RECORD +0 -5
  74. ECOv003_L2T_STARS-1.0.0.dist-info/top_level.txt +0 -1
  75. {ECOv003_L2T_STARS-1.0.0.dist-info → ecov003_l2t_stars-1.1.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,248 @@
1
+ from os.path import exists
2
+ import logging
3
+
4
+ from ECOv003_granules import L2TSTARS
5
+
6
+ from .prior import Prior
7
+ from .generate_filename import generate_filename
8
+ from .generate_model_state_tile_date_directory import generate_model_state_tile_date_directory
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ def load_prior(
13
+ tile: str,
14
+ target_resolution: int,
15
+ model_directory: str,
16
+ L2T_STARS_prior_filename: str) -> Prior:
17
+ """
18
+ Loads a prior L2T_STARS product if available and extracts its components.
19
+
20
+ This function attempts to load a previously generated L2T_STARS product
21
+ to use its NDVI and albedo mean, uncertainty, and bias as prior information
22
+ for the current data fusion run.
23
+
24
+ Args:
25
+ tile (str): The HLS tile ID.
26
+ target_resolution (int): The target resolution of the L2T_STARS product.
27
+ model_directory (str): The base directory for model state files.
28
+ L2T_STARS_prior_filename (str): The filename of the prior L2T_STARS product (zip file).
29
+
30
+ Returns:
31
+ Prior: A Prior object containing paths to the prior data components
32
+ and a flag indicating if a valid prior was loaded.
33
+ """
34
+ using_prior = False
35
+ prior_date_UTC = None
36
+ prior_NDVI_filename = None
37
+ prior_NDVI_UQ_filename = None
38
+ prior_NDVI_bias_filename = None
39
+ prior_NDVI_bias_UQ_filename = None
40
+ prior_albedo_filename = None
41
+ prior_albedo_UQ_filename = None
42
+ prior_albedo_bias_filename = None
43
+ prior_albedo_bias_UQ_filename = None
44
+
45
+ # Check if a prior L2T_STARS product is specified and exists
46
+ if L2T_STARS_prior_filename is not None and exists(L2T_STARS_prior_filename):
47
+ logger.info(f"Loading prior L2T STARS product: {L2T_STARS_prior_filename}")
48
+ try:
49
+ # Initialize L2TSTARS object from the prior product
50
+ L2T_STARS_prior_granule = L2TSTARS(L2T_STARS_prior_filename)
51
+ prior_date_UTC = L2T_STARS_prior_granule.date_UTC
52
+ logger.info(f"Prior date: {cl.time(prior_date_UTC)}")
53
+
54
+ # Extract NDVI and albedo mean and uncertainty rasters
55
+ NDVI_prior_mean = L2T_STARS_prior_granule.NDVI
56
+ NDVI_prior_UQ = L2T_STARS_prior_granule.NDVI_UQ
57
+ albedo_prior_mean = L2T_STARS_prior_granule.albedo
58
+ albedo_prior_UQ = L2T_STARS_prior_granule.albedo_UQ
59
+
60
+ # Define the directory for storing prior model state files
61
+ prior_tile_date_directory = generate_model_state_tile_date_directory(
62
+ model_directory=model_directory, tile=tile, date_UTC=prior_date_UTC
63
+ )
64
+
65
+ # Generate and save filenames for all prior components
66
+ prior_NDVI_filename = generate_filename(
67
+ directory=prior_tile_date_directory,
68
+ variable="NDVI",
69
+ date_UTC=prior_date_UTC,
70
+ tile=tile,
71
+ cell_size=target_resolution,
72
+ )
73
+ NDVI_prior_mean.to_geotiff(prior_NDVI_filename)
74
+
75
+ prior_NDVI_UQ_filename = generate_filename(
76
+ directory=prior_tile_date_directory,
77
+ variable="NDVI.UQ",
78
+ date_UTC=prior_date_UTC,
79
+ tile=tile,
80
+ cell_size=target_resolution,
81
+ )
82
+ NDVI_prior_UQ.to_geotiff(prior_NDVI_UQ_filename)
83
+
84
+ # Note: Prior bias files might not always exist in older products.
85
+ # Assuming they could be extracted from L2T_STARS_prior_granule if present.
86
+ # For simplicity, these are placeholders and would need proper extraction logic
87
+ # from the L2TSTARS granule if they are actual components.
88
+ # For now, we set them based on `generate_filename` only if a bias layer is retrieved.
89
+ # If the bias layers are not explicitly part of `L2TSTARS` object, these will be None
90
+ # unless written explicitly during prior creation.
91
+ prior_NDVI_bias_filename = generate_filename(
92
+ directory=prior_tile_date_directory,
93
+ variable="NDVI.bias",
94
+ date_UTC=prior_date_UTC,
95
+ tile=tile,
96
+ cell_size=target_resolution,
97
+ )
98
+ # Assuming L2T_STARS_prior_granule has a .NDVI_bias attribute
99
+ if hasattr(L2T_STARS_prior_granule, "NDVI_bias") and L2T_STARS_prior_granule.NDVI_bias is not None:
100
+ L2T_STARS_prior_granule.NDVI_bias.to_geotiff(prior_NDVI_bias_filename)
101
+ else:
102
+ prior_NDVI_bias_filename = None # Set to None if not available
103
+
104
+ prior_NDVI_bias_UQ_filename = generate_filename(
105
+ directory=prior_tile_date_directory,
106
+ variable="NDVI.bias.UQ",
107
+ date_UTC=prior_date_UTC,
108
+ tile=tile,
109
+ cell_size=target_resolution,
110
+ )
111
+ # Assuming L2T_STARS_prior_granule has a .NDVI_bias_UQ attribute
112
+ if hasattr(L2T_STARS_prior_granule, "NDVI_bias_UQ") and L2T_STARS_prior_granule.NDVI_bias_UQ is not None:
113
+ L2T_STARS_prior_granule.NDVI_bias_UQ.to_geotiff(prior_NDVI_bias_UQ_filename)
114
+ else:
115
+ prior_NDVI_bias_UQ_filename = None # Set to None if not available
116
+
117
+
118
+ prior_albedo_filename = generate_filename(
119
+ directory=prior_tile_date_directory,
120
+ variable="albedo",
121
+ date_UTC=prior_date_UTC,
122
+ tile=tile,
123
+ cell_size=target_resolution,
124
+ )
125
+ albedo_prior_mean.to_geotiff(prior_albedo_filename)
126
+
127
+ prior_albedo_UQ_filename = generate_filename(
128
+ directory=prior_tile_date_directory,
129
+ variable="albedo.UQ",
130
+ date_UTC=prior_date_UTC,
131
+ tile=tile,
132
+ cell_size=target_resolution,
133
+ )
134
+ albedo_prior_UQ.to_geotiff(prior_albedo_UQ_filename)
135
+
136
+ prior_albedo_bias_filename = generate_filename(
137
+ directory=prior_tile_date_directory,
138
+ variable="albedo.bias",
139
+ date_UTC=prior_date_UTC,
140
+ tile=tile,
141
+ cell_size=target_resolution,
142
+ )
143
+ # Assuming L2T_STARS_prior_granule has a .albedo_bias attribute
144
+ if hasattr(L2T_STARS_prior_granule, "albedo_bias") and L2T_STARS_prior_granule.albedo_bias is not None:
145
+ L2T_STARS_prior_granule.albedo_bias.to_geotiff(prior_albedo_bias_filename)
146
+ else:
147
+ prior_albedo_bias_filename = None # Set to None if not available
148
+
149
+ prior_albedo_bias_UQ_filename = generate_filename(
150
+ directory=prior_tile_date_directory,
151
+ variable="albedo.bias.UQ",
152
+ date_UTC=prior_date_UTC,
153
+ tile=tile,
154
+ cell_size=target_resolution,
155
+ )
156
+ # Assuming L2T_STARS_prior_granule has a .albedo_bias_UQ attribute
157
+ if hasattr(L2T_STARS_prior_granule, "albedo_bias_UQ") and L2T_STARS_prior_granule.albedo_bias_UQ is not None:
158
+ L2T_STARS_prior_granule.albedo_bias_UQ.to_geotiff(prior_albedo_bias_UQ_filename)
159
+ else:
160
+ prior_albedo_bias_UQ_filename = None # Set to None if not available
161
+
162
+
163
+ using_prior = True # Mark that a prior was successfully loaded
164
+ except Exception as e:
165
+ logger.warning(f"Could not load prior L2T STARS product: {L2T_STARS_prior_filename}. Reason: {e}")
166
+ using_prior = False # Ensure using_prior is False if loading fails
167
+
168
+ # Verify that all expected prior files exist, otherwise disable using_prior
169
+ # This ensures a partial prior (e.g., only NDVI but not albedo) isn't used
170
+ if prior_NDVI_filename is not None and exists(prior_NDVI_filename):
171
+ logger.info(f"Prior NDVI ready: {prior_NDVI_filename}")
172
+ else:
173
+ logger.info(f"Prior NDVI not found: {prior_NDVI_filename}")
174
+ using_prior = False
175
+
176
+ if prior_NDVI_UQ_filename is not None and exists(prior_NDVI_UQ_filename):
177
+ logger.info(f"Prior NDVI UQ ready: {prior_NDVI_UQ_filename}")
178
+ else:
179
+ logger.info(f"Prior NDVI UQ not found: {prior_NDVI_UQ_filename}")
180
+ using_prior = False
181
+
182
+ if prior_NDVI_bias_filename is not None and exists(prior_NDVI_bias_filename):
183
+ logger.info(f"Prior NDVI bias ready: {prior_NDVI_bias_filename}")
184
+ else:
185
+ logger.info(f"Prior NDVI bias not found: {prior_NDVI_bias_filename}")
186
+ using_prior = False
187
+
188
+ if prior_NDVI_bias_UQ_filename is not None and exists(prior_NDVI_bias_UQ_filename):
189
+ logger.info(f"Prior NDVI bias UQ ready: {prior_NDVI_bias_UQ_filename}")
190
+ else:
191
+ logger.info(f"Prior NDVI bias UQ not found: {prior_NDVI_bias_UQ_filename}")
192
+ using_prior = False
193
+
194
+ if prior_albedo_filename is not None and exists(prior_albedo_filename):
195
+ logger.info(f"Prior albedo ready: {prior_albedo_filename}")
196
+ else:
197
+ logger.info(f"Prior albedo not found: {prior_albedo_filename}")
198
+ using_prior = False
199
+
200
+ if prior_albedo_UQ_filename is not None and exists(prior_albedo_UQ_filename):
201
+ logger.info(f"Prior albedo UQ ready: {prior_albedo_UQ_filename}")
202
+ else:
203
+ logger.info(f"Prior albedo UQ not found: {prior_albedo_UQ_filename}")
204
+ using_prior = False
205
+
206
+ if prior_albedo_bias_filename is not None and exists(prior_albedo_bias_filename):
207
+ logger.info(f"Prior albedo bias ready: {prior_albedo_bias_filename}")
208
+ else:
209
+ logger.info(f"Prior albedo bias not found: {prior_albedo_bias_filename}")
210
+ using_prior = False
211
+
212
+ if prior_albedo_bias_UQ_filename is not None and exists(
213
+ prior_albedo_bias_UQ_filename
214
+ ):
215
+ logger.info(f"Prior albedo bias UQ ready: {prior_albedo_bias_UQ_filename}")
216
+ else:
217
+ logger.info(f"Prior albedo bias UQ not found: {prior_albedo_bias_UQ_filename}")
218
+ using_prior = False
219
+
220
+ # Final check: if any of the critical prior files are missing, do not use prior
221
+ if not all([prior_NDVI_filename, prior_NDVI_UQ_filename, prior_albedo_filename, prior_albedo_UQ_filename]):
222
+ logger.warning("One or more required prior (mean/UQ) files are missing. Prior will not be used.")
223
+ using_prior = False
224
+ prior_NDVI_filename = None
225
+ prior_NDVI_UQ_filename = None
226
+ prior_albedo_filename = None
227
+ prior_albedo_UQ_filename = None
228
+
229
+ # FIXME where are `prior_NDVI_flag_filename` and `prior_albedo_flag_filename` defined?
230
+
231
+ # Create and return the Prior object
232
+ prior = Prior(
233
+ using_prior=using_prior,
234
+ prior_date_UTC=prior_date_UTC,
235
+ L2T_STARS_prior_filename=L2T_STARS_prior_filename,
236
+ prior_NDVI_filename=prior_NDVI_filename,
237
+ prior_NDVI_UQ_filename=prior_NDVI_UQ_filename,
238
+ prior_NDVI_flag_filename=prior_NDVI_flag_filename,
239
+ prior_NDVI_bias_filename=prior_NDVI_bias_filename,
240
+ prior_NDVI_bias_UQ_filename=prior_NDVI_bias_UQ_filename,
241
+ prior_albedo_filename=prior_albedo_filename,
242
+ prior_albedo_UQ_filename=prior_albedo_UQ_filename,
243
+ prior_albedo_flag_filename=prior_albedo_flag_filename,
244
+ prior_albedo_bias_filename=prior_albedo_bias_filename,
245
+ prior_albedo_bias_UQ_filename=prior_albedo_bias_UQ_filename,
246
+ )
247
+
248
+ 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