loone-data-prep 1.2.3__py3-none-any.whl → 1.2.4__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.
@@ -2,8 +2,11 @@ import os
2
2
  from herbie import FastHerbie
3
3
  from datetime import datetime
4
4
  import pandas as pd
5
- from retry_requests import retry
5
+ from retry_requests import retry as retry_requests
6
+ from retry import retry
6
7
  import warnings
8
+ from typing import Tuple
9
+ from loone_data_prep.herbie_utils import get_fast_herbie_object
7
10
 
8
11
 
9
12
  def generate_wind_forecasts(output_dir):
@@ -26,7 +29,8 @@ def generate_wind_forecasts(output_dir):
26
29
  }
27
30
 
28
31
  today_str = datetime.today().strftime('%Y-%m-%d 00:00')
29
- FH = FastHerbie([today_str], model="ifs", fxx=range(0, 360, 3))
32
+ FH = get_fast_herbie_object(today_str)
33
+ print("FastHerbie initialized.")
30
34
  dfs = []
31
35
 
32
36
  variables = {
@@ -45,37 +49,20 @@ def generate_wind_forecasts(output_dir):
45
49
  "latitude": [point.latitude]
46
50
  })
47
51
 
52
+ # Loop through variables for current point and extract data
48
53
  for var_key, var_name in variables.items():
54
+ # Get the current variable data at the current point
49
55
  print(f" Variable: {var_key}")
56
+ try:
57
+ df, var_name_actual = _download_herbie_variable(FH, var_key, var_name, point_df)
58
+ except Exception as e:
59
+ print(f"Error processing {var_key} for Point {index + 1} ({point.latitude}, {point.longitude}): {e}")
60
+ print(f'Skipping {var_key}')
61
+ continue
50
62
 
51
- # Download and load dataset
52
- FH.download(f":{var_key}")
53
- ds = FH.xarray(f":{var_key}", backend_kwargs={"decode_timedelta": True})
54
-
55
- # Extract point data
56
- dsi = ds.herbie.pick_points(point_df, method="nearest")
57
-
58
- # Get actual variable name
59
- if var_name == "10u":
60
- var_name_actual = "u10" # Map 10u to u10
61
- elif var_name == "10v":
62
- var_name_actual = "v10" # Map 10v to v10
63
- elif var_name == "2t":
64
- var_name_actual = "t2m" #TODO: check that this is correct
65
-
66
- # Convert to DataFrame
67
- time_series = dsi[var_name_actual].squeeze()
68
- df = time_series.to_dataframe().reset_index()
69
-
70
- # Handle datetime columns
71
- if "valid_time" in df.columns:
72
- df = df.rename(columns={"valid_time": "datetime"})
73
- elif "step" in df.columns and "time" in dsi.coords:
74
- df["datetime"] = dsi.time.values[0] + df["step"]
75
-
76
- # Retain necessary columns
77
- df = df[["datetime", var_name_actual]].drop_duplicates()
78
- dfs.append((index, var_name_actual, df))
63
+ # Append the DataFrame and variable name to the list
64
+ if not df.empty:
65
+ dfs.append((index, var_name_actual, df))
79
66
 
80
67
  # Merge and process data per point
81
68
  results = {}
@@ -125,3 +112,59 @@ def generate_wind_forecasts(output_dir):
125
112
  filepath = os.path.join(output_dir, airt_file_map[key])
126
113
  df_airt.to_csv(filepath, index=False)
127
114
 
115
+
116
+ @retry(Exception, tries=5, delay=15, max_delay=60, backoff=2)
117
+ def _download_herbie_variable(fast_herbie_object: FastHerbie, variable_key: str, variable_name: str, point_df: pd.DataFrame) -> Tuple[pd.DataFrame, str]:
118
+ """
119
+ Download a specific variable from the Herbie API.
120
+
121
+ Args:
122
+ fast_herbie_object: An instance of the FastHerbie class.
123
+ variable_key: The key of the variable to download.
124
+ variable_name: The name of the variable to download.
125
+ point_df: A DataFrame containing the point of interest (longitude and latitude).
126
+
127
+ Returns:
128
+ A DataFrame containing the downloaded variable data.
129
+
130
+ Example:
131
+ point_df = pd.DataFrame({"longitude": [-80.7934], "latitude": [27.1389]})
132
+ df, var_name_actual = _download_herbie_variable(FastHerbie('2020-05-16 00:00', model='ifs', fxx=range(0, 360, 3)), '10u', '10u', point_df)
133
+ """
134
+ # Download and load dataset
135
+ fast_herbie_object.download(f":{variable_key}")
136
+ ds = fast_herbie_object.xarray(f":{variable_key}", backend_kwargs={"decode_timedelta": True})
137
+
138
+ # Extract point data
139
+ dsi = ds.herbie.pick_points(point_df, method="nearest")
140
+
141
+ # Close and delete the original dataset to free up resources
142
+ ds.close()
143
+ del ds
144
+
145
+ # Get actual variable name
146
+ if variable_name == "10u":
147
+ var_name_actual = "u10" # Map 10u to u10
148
+ elif variable_name == "10v":
149
+ var_name_actual = "v10" # Map 10v to v10
150
+ elif variable_name == "2t":
151
+ var_name_actual = "t2m" #TODO: check that this is correct
152
+
153
+ # Convert to DataFrame
154
+ time_series = dsi[var_name_actual].squeeze()
155
+ df = time_series.to_dataframe().reset_index()
156
+
157
+ # Handle datetime columns
158
+ if "valid_time" in df.columns:
159
+ df = df.rename(columns={"valid_time": "datetime"})
160
+ elif "step" in df.columns and "time" in dsi.coords:
161
+ df["datetime"] = dsi.time.values[0] + df["step"]
162
+
163
+ # Close and delete the intermediate dataset to free memory
164
+ dsi.close()
165
+ del dsi, time_series
166
+
167
+ # Retain necessary columns
168
+ df = df[["datetime", var_name_actual]].drop_duplicates()
169
+
170
+ return df, var_name_actual
@@ -4,13 +4,15 @@ import pandas as pd
4
4
  import openmeteo_requests
5
5
  import argparse
6
6
  import requests_cache
7
- from retry_requests import retry
7
+ from retry_requests import retry as retry_requests
8
+ from retry import retry
8
9
  import warnings
10
+ from loone_data_prep.herbie_utils import get_fast_herbie_object
9
11
 
10
12
  warnings.filterwarnings("ignore", message="Will not remove GRIB file because it previously existed.")
11
13
 
12
14
 
13
- def download_weather_forecast (file_path):
15
+ def download_weather_forecast(file_path):
14
16
  # Get today's date in the required format
15
17
  today_str = datetime.today().strftime('%Y-%m-%d 00:00')
16
18
 
@@ -22,121 +24,163 @@ def download_weather_forecast (file_path):
22
24
  "10v": "10v",
23
25
  }
24
26
 
25
- # Define point of interest
26
- points = pd.DataFrame({"longitude": [-80.7976], "latitude": [26.9690]})
27
-
28
27
  # Initialize FastHerbie
29
- FH = FastHerbie([today_str], model="ifs", fxx=range(0, 360, 3))
28
+ FH = get_fast_herbie_object(today_str)
29
+ print("FastHerbie initialized.")
30
+
30
31
  dfs = []
31
32
 
32
33
  for var_key, var_name in variables.items():
34
+ # Download the current variable
33
35
  print(f"Processing {var_key}...")
36
+ try:
37
+ df = _download_herbie_variable(FH, var_key, var_name)
38
+ except Exception as e:
39
+ print(f"Error processing {var_key}: {e}")
40
+ print(f'Skipping {var_key}')
41
+ continue
34
42
 
35
- # Download and load the dataset
36
- FH.download(f":{var_key}")
37
- ds = FH.xarray(f":{var_key}", backend_kwargs={"decode_timedelta": True})
38
-
39
- # Extract point data
40
- dsi = ds.herbie.pick_points(points, method="nearest")
41
-
42
- # Extract the correct variable name dynamically
43
- if var_name == "10u":
44
- var_name_actual = "u10" # Map 10u to u10
45
- elif var_name == "10v":
46
- var_name_actual = "v10" # Map 10v to v10
47
- else:
48
- var_name_actual = var_name # For ssrd and tp, use the same name
49
-
50
- # Extract time series
51
- time_series = dsi[var_name_actual].squeeze()
52
-
53
- # Convert to DataFrame
54
- df = time_series.to_dataframe().reset_index()
55
-
56
- # Convert `valid_time` to datetime
57
- if "valid_time" in df.columns:
58
- df = df.rename(columns={"valid_time": "datetime"})
59
- elif "step" in df.columns and "time" in dsi.coords:
60
- df["datetime"] = dsi.time.values[0] + df["step"]
61
-
62
- # Keep only datetime and variable of interest
63
- df = df[["datetime", var_name_actual]].drop_duplicates()
64
-
65
43
  # Append to list
66
- dfs.append(df)
67
-
68
- # Print extracted data
69
- # print(df)
70
-
71
- # Merge all variables into a single DataFrame
72
- final_df = dfs[0]
73
- for df in dfs[1:]:
74
- final_df = final_df.merge(df, on="datetime", how="outer")
75
- print(final_df)
76
- # Calculate wind speed
77
- final_df["wind_speed"] = (final_df["u10"] ** 2 + final_df["v10"] ** 2) ** 0.5
78
-
79
- #rainfall corrected: OLS Regression Equation: Corrected Forecast = 0.7247 * Forecast + 0.1853
80
- final_df["tp_corrected"] = 0.7247 * final_df["tp"] + 0.1853
81
-
82
- #wind speed correction: Corrected Forecast = 0.4167 * Forecast + 4.1868
83
- final_df["wind_speed_corrected"] = 0.4167 * final_df["wind_speed"] + 4.1868
84
-
85
- #radiation correction will need to be fixed because it was done on fdir instead of ssdr
86
- #radiation corrected: Corrected Forecast = 0.0553 * Forecast - 0.0081
87
- final_df["ssrd_corrected"] = 0.0553 * final_df["ssrd"] - 0.0081
88
-
89
- # Setup the Open-Meteo API client with cache and retry on error
90
- cache_session = requests_cache.CachedSession('.cache', expire_after = 3600)
91
- retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
92
- openmeteo = openmeteo_requests.Client(session = retry_session)
93
-
94
- # Make sure all required weather variables are listed here
95
- # The order of variables in hourly or daily is important to assign them correctly below
96
- url = "https://api.open-meteo.com/v1/forecast"
97
- params = {
98
- "latitude": 26.9690,
99
- "longitude": -80.7976,
100
- "hourly": "evapotranspiration",
101
- "forecast_days": 16,
102
- "models": "gfs_seamless"
103
- }
104
- responses = openmeteo.weather_api(url, params=params)
105
-
106
-
107
- # Process first location. Add a for-loop for multiple locations or weather models
108
- response = responses[0]
109
-
110
- hourly = response.Hourly()
111
- hourly_evapotranspiration = hourly.Variables(0).ValuesAsNumpy()
112
-
113
- hourly_data = {"date": pd.date_range(
114
- start = pd.to_datetime(hourly.Time(), unit = "s", utc = True),
115
- end = pd.to_datetime(hourly.TimeEnd(), unit = "s", utc = True),
116
- freq = pd.Timedelta(seconds = hourly.Interval()),
117
- inclusive = "left"
118
- )}
119
-
120
- hourly_data["evapotranspiration"] = hourly_evapotranspiration
121
-
122
- hourly_dataframe = pd.DataFrame(data = hourly_data)
123
-
124
- # Convert datetime to date for merging
125
- final_df['date'] = final_df['datetime']
126
- # Ensure final_df['date'] is timezone-aware (convert to UTC)
127
- final_df['date'] = pd.to_datetime(final_df['date'], utc=True)
128
-
129
- # Ensure hourly_dataframe['date'] is also timezone-aware (convert to UTC)
130
- hourly_dataframe['date'] = pd.to_datetime(hourly_dataframe['date'], utc=True)
131
-
132
- # Merge while keeping only matching dates from final_df
133
- merged_df = final_df.merge(hourly_dataframe, on='date', how='left')
134
-
135
- # Print final combined DataFrame
136
- merged_df.drop(columns=['date'], inplace=True)
137
- # print(merged_df)
138
-
139
- merged_df.to_csv(file_path, index=False)
44
+ if not df.empty:
45
+ dfs.append(df)
46
+
47
+ try:
48
+ # Merge all variables into a single DataFrame
49
+ final_df = dfs[0]
50
+ for df in dfs[1:]:
51
+ final_df = final_df.merge(df, on="datetime", how="outer")
52
+ print(final_df)
53
+ # Calculate wind speed
54
+ final_df["wind_speed"] = (final_df["u10"] ** 2 + final_df["v10"] ** 2) ** 0.5
55
+
56
+ #rainfall corrected: OLS Regression Equation: Corrected Forecast = 0.7247 * Forecast + 0.1853
57
+ final_df["tp_corrected"] = 0.7247 * final_df["tp"] + 0.1853
58
+
59
+ #wind speed correction: Corrected Forecast = 0.4167 * Forecast + 4.1868
60
+ final_df["wind_speed_corrected"] = 0.4167 * final_df["wind_speed"] + 4.1868
61
+
62
+ #radiation correction will need to be fixed because it was done on fdir instead of ssdr
63
+ #radiation corrected: Corrected Forecast = 0.0553 * Forecast - 0.0081
64
+ final_df["ssrd_corrected"] = 0.0553 * final_df["ssrd"] - 0.0081
65
+ except Exception as e:
66
+ print(f'Error correcting herbie weather data: {e}')
67
+
68
+ try:
69
+ # Setup the Open-Meteo API client with cache and retry on error
70
+ cache_session = requests_cache.CachedSession('.cache', expire_after = 3600)
71
+ retry_session = retry_requests(cache_session, retries = 5, backoff_factor = 0.2)
72
+ openmeteo = openmeteo_requests.Client(session = retry_session)
73
+
74
+ # Make sure all required weather variables are listed here
75
+ # The order of variables in hourly or daily is important to assign them correctly below
76
+ url = "https://api.open-meteo.com/v1/forecast"
77
+ params = {
78
+ "latitude": 26.9690,
79
+ "longitude": -80.7976,
80
+ "hourly": "evapotranspiration",
81
+ "forecast_days": 16,
82
+ "models": "gfs_seamless"
83
+ }
84
+ responses = openmeteo.weather_api(url, params=params)
85
+
86
+
87
+ # Process first location. Add a for-loop for multiple locations or weather models
88
+ response = responses[0]
89
+
90
+ hourly = response.Hourly()
91
+ hourly_evapotranspiration = hourly.Variables(0).ValuesAsNumpy()
92
+
93
+ hourly_data = {"date": pd.date_range(
94
+ start = pd.to_datetime(hourly.Time(), unit = "s", utc = True),
95
+ end = pd.to_datetime(hourly.TimeEnd(), unit = "s", utc = True),
96
+ freq = pd.Timedelta(seconds = hourly.Interval()),
97
+ inclusive = "left"
98
+ )}
99
+
100
+ hourly_data["evapotranspiration"] = hourly_evapotranspiration
101
+
102
+ hourly_dataframe = pd.DataFrame(data = hourly_data)
103
+
104
+ # Convert datetime to date for merging
105
+ final_df['date'] = final_df['datetime']
106
+ # Ensure final_df['date'] is timezone-aware (convert to UTC)
107
+ final_df['date'] = pd.to_datetime(final_df['date'], utc=True)
108
+
109
+ # Ensure hourly_dataframe['date'] is also timezone-aware (convert to UTC)
110
+ hourly_dataframe['date'] = pd.to_datetime(hourly_dataframe['date'], utc=True)
111
+
112
+ # Merge while keeping only matching dates from final_df
113
+ merged_df = final_df.merge(hourly_dataframe, on='date', how='left')
114
+
115
+ # Print final combined DataFrame
116
+ merged_df.drop(columns=['date'], inplace=True)
117
+ # print(merged_df)
118
+
119
+ merged_df.to_csv(file_path, index=False)
120
+ except Exception as e:
121
+ print(f'Error retrieving openmeteo weather data: {e}')
122
+
123
+
124
+ @retry(Exception, tries=5, delay=15, max_delay=60, backoff=2)
125
+ def _download_herbie_variable(fast_herbie_object: FastHerbie, variable_key: str, variable_name: str) -> pd.DataFrame:
126
+ """
127
+ Download a specific variable from the Herbie API.
128
+
129
+ Args:
130
+ fast_herbie_object: An instance of the FastHerbie class.
131
+ variable_key: The key of the variable to download.
132
+ variable_name: The name of the variable to download.
133
+
134
+ Returns:
135
+ A DataFrame containing the downloaded variable data.
136
+
137
+ Example:
138
+ df = _download_herbie_variable(FastHerbie('2020-05-16 00:00', model='ifs', fxx=range(0, 360, 3)), '10u', '10u')
139
+ """
140
+ # Define point of interest
141
+ points = pd.DataFrame({"longitude": [-80.7976], "latitude": [26.9690]})
142
+
143
+ # Download and load the dataset
144
+ fast_herbie_object.download(f":{variable_key}")
145
+ ds = fast_herbie_object.xarray(f":{variable_key}", backend_kwargs={"decode_timedelta": True})
146
+
147
+ # Extract point data
148
+ dsi = ds.herbie.pick_points(points, method="nearest")
149
+
150
+ # Close and delete the original dataset to free up resources
151
+ ds.close()
152
+ del ds
153
+
154
+ # Extract the correct variable name dynamically
155
+ if variable_name == "10u":
156
+ var_name_actual = "u10" # Map 10u to u10
157
+ elif variable_name == "10v":
158
+ var_name_actual = "v10" # Map 10v to v10
159
+ else:
160
+ var_name_actual = variable_name # For ssrd and tp, use the same name
161
+
162
+ # Extract time series
163
+ time_series = dsi[var_name_actual].squeeze()
164
+
165
+ # Convert to DataFrame
166
+ df = time_series.to_dataframe().reset_index()
167
+
168
+ # Convert `valid_time` to datetime
169
+ if "valid_time" in df.columns:
170
+ df = df.rename(columns={"valid_time": "datetime"})
171
+ elif "step" in df.columns and "time" in dsi.coords:
172
+ df["datetime"] = dsi.time.values[0] + df["step"]
173
+
174
+ # Keep only datetime and variable of interest
175
+ df = df[["datetime", var_name_actual]].drop_duplicates()
176
+
177
+ # Print extracted data
178
+ # print(df)
179
+
180
+ # Clean up intermediate datasets to free memory
181
+ del dsi, time_series
182
+
183
+ return df
140
184
 
141
185
 
142
186
  def main():
@@ -0,0 +1,29 @@
1
+ from retry import retry
2
+ from herbie import FastHerbie
3
+
4
+
5
+ class NoGribFilesFoundError(Exception):
6
+ """Raised when no GRIB files are found for the specified date/model run."""
7
+ pass
8
+
9
+
10
+ @retry(NoGribFilesFoundError, tries=5, delay=15, max_delay=60, backoff=2)
11
+ def get_fast_herbie_object(date: str) -> FastHerbie:
12
+ """
13
+ Get a FastHerbie object for the specified date. Raises an exception when no GRIB files are found.
14
+
15
+ Args:
16
+ date: pandas-parsable datetime string
17
+
18
+ Returns:
19
+ A FastHerbie object configured for the specified date.
20
+
21
+ Raises:
22
+ NoGribFilesFoundError: If no GRIB files are found for the specified date.
23
+ """
24
+ fast_herbie = FastHerbie([date], model="ifs", fxx=range(0, 360, 3))
25
+
26
+ if len(fast_herbie.file_exists) == 0:
27
+ raise NoGribFilesFoundError(f"No GRIB files found for the specified date {date}.")
28
+
29
+ return fast_herbie
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loone_data_prep
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: Prepare data to run the LOONE model.
5
5
  Author-email: Osama Tarabih <osamatarabih@usf.edu>
6
6
  Maintainer-email: Michael Souffront <msouffront@aquaveo.com>, James Dolinar <jdolinar@aquaveo.com>
@@ -2,6 +2,7 @@ loone_data_prep/GEOGLOWS_LOONE_DATA_PREP.py,sha256=gfpnaOTjZ-YhWqOEvOaDvear4_59I
2
2
  loone_data_prep/LOONE_DATA_PREP.py,sha256=vEWcGHKN10ipLk9o5I5aKu_LPfDyFW3HBJ8GgqISYjA,69315
3
3
  loone_data_prep/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  loone_data_prep/data_analyses_fns.py,sha256=BZ7famrSKoUfExQvZfbl72CyADHLb-zzgdWZ-kLJxcQ,4603
5
+ loone_data_prep/herbie_utils.py,sha256=O5Lcn6lSWUKjJwWhak7U3eyUPxo4jH59xdfBgl5ExJQ,914
5
6
  loone_data_prep/utils.py,sha256=UlNc84ofh3ZY3lYsgQmDsgGgohXIBwZ0bK9rX6SgGF4,35730
6
7
  loone_data_prep/flow_data/S65E_total.py,sha256=szNUfj0EyyyDzuKNhTGAZtWc5owiOpxYS55YTt4u19k,2835
7
8
  loone_data_prep/flow_data/__init__.py,sha256=u7fENFUZsJjyl13Bc9ZE47sHMKmjxtqXhV9t7vDTm7Y,93
@@ -11,7 +12,7 @@ loone_data_prep/flow_data/get_inflows.py,sha256=xKuSyJBdPrpjqMdRiyNDyxwdhYVIgLhi
11
12
  loone_data_prep/flow_data/get_outflows.py,sha256=x7aisIkbXoTkcubFQLDghX-P8lztPq-tU0dQzoVRTtQ,5620
12
13
  loone_data_prep/flow_data/hydro.py,sha256=5MwrzSUTCgPgeC_YGhz-en1CbOMp379Qf5zjpJlp-HM,5312
13
14
  loone_data_prep/forecast_scripts/Chla_merged.py,sha256=PxVEbTrqHEka6Jg0QjEC6qfFtPNzY-0_71WmlelAfPY,1225
14
- loone_data_prep/forecast_scripts/create_forecast_LOWs.py,sha256=_n6haJvGWuCfcgXO1x3ondmsaEDxzPlhJJQJHQhhd10,4864
15
+ loone_data_prep/forecast_scripts/create_forecast_LOWs.py,sha256=xUYO0_9EbtVDX6LPBAfDFyvQQIFN7dNaNYFO4D5pe8Y,6591
15
16
  loone_data_prep/forecast_scripts/forecast_stages.py,sha256=6S6aHlYi2_t6GAh901KBiBWPueYCwAzyb-AliHJexoU,1373
16
17
  loone_data_prep/forecast_scripts/get_Chla_predicted.py,sha256=wnGFJlu2zyO1QSUiQ3W8iAcLOtkDZpLhuRr037Nmgb4,4759
17
18
  loone_data_prep/forecast_scripts/get_NO_Loads_predicted.py,sha256=MvJNgY7KPkjyot2BYInQCcp5lg8_N_D_SLSt8WpUmHQ,4200
@@ -19,7 +20,7 @@ loone_data_prep/forecast_scripts/loone_q_predict.py,sha256=k8ndTnsRly4BxGS52Gznc
19
20
  loone_data_prep/forecast_scripts/loone_wq_predict.py,sha256=xCiH6QScTYdeZyAhqoqNiJEDTFoXJPh-Yma9VGN_-GY,2123
20
21
  loone_data_prep/forecast_scripts/predict_PI.py,sha256=f0n2-gt5t9FKNdpJ5QGpyP2QBFLDGetYzfTYL95Vi_8,1937
21
22
  loone_data_prep/forecast_scripts/trib_cond.py,sha256=LlMxD0a9jwtQ9grI4Ho0KpTgphl6VAjg1cBUtfXZ01A,4030
22
- loone_data_prep/forecast_scripts/weather_forecast.py,sha256=AIHRjcdGUuA2a15ZcLyYws1gtH016QRU0bWIp4Ty2K0,5457
23
+ loone_data_prep/forecast_scripts/weather_forecast.py,sha256=5RFA2Pg4j9Df3633SEt6vEAQH0HXjR3TVDgNqYqETEY,7108
23
24
  loone_data_prep/water_level_data/__init__.py,sha256=rgHDDkwccemsZnwUlw2M0h2ML4KmI89yPscmLoxbEHM,43
24
25
  loone_data_prep/water_level_data/get_all.py,sha256=arPSWpb0XfQm0GKZJmoWhWdLuuNDxtGVX6_6UuD1_Vs,10885
25
26
  loone_data_prep/water_level_data/hydro.py,sha256=PtsNdMXe1Y4e5CzEyLH6nJx_xv8sB90orGcSgxt7nao,3653
@@ -30,8 +31,8 @@ loone_data_prep/water_quality_data/wq.py,sha256=sl6G3iDCk6QUzpHTXPHpRZNMBG0-wHuc
30
31
  loone_data_prep/weather_data/__init__.py,sha256=TX58EPgGRzEK_LmLze79lC4L7kU_j3yZf5_iC4nOIP4,45
31
32
  loone_data_prep/weather_data/get_all.py,sha256=aCufuxORU51XhXt7LN9wN_V4qtjNt1qRC1UKlI2b3Ko,6918
32
33
  loone_data_prep/weather_data/weather.py,sha256=hvceksrGSnDkCjheBVBuPgY1DrdR0ZAtrFB-K2tYTtk,12043
33
- loone_data_prep-1.2.3.dist-info/licenses/LICENSE,sha256=rR1QKggtQUbAoYu2SW1ouI5xPqt9g4jvRRpZ0ZfnuqQ,1497
34
- loone_data_prep-1.2.3.dist-info/METADATA,sha256=P8v3Ah3cioOIAnmQrUkUd6PsNbJ4iaKbmu8SuzB92QY,4343
35
- loone_data_prep-1.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- loone_data_prep-1.2.3.dist-info/top_level.txt,sha256=wDyJMJiCO5huTAuNmvxpjFxtvGaq_8Tr4hFFcXf8jLE,16
37
- loone_data_prep-1.2.3.dist-info/RECORD,,
34
+ loone_data_prep-1.2.4.dist-info/licenses/LICENSE,sha256=rR1QKggtQUbAoYu2SW1ouI5xPqt9g4jvRRpZ0ZfnuqQ,1497
35
+ loone_data_prep-1.2.4.dist-info/METADATA,sha256=WIXZJw2ShnnkeaZGRYL7JtjE-yIIDerzWtFPCxt9SVQ,4343
36
+ loone_data_prep-1.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ loone_data_prep-1.2.4.dist-info/top_level.txt,sha256=wDyJMJiCO5huTAuNmvxpjFxtvGaq_8Tr4hFFcXf8jLE,16
38
+ loone_data_prep-1.2.4.dist-info/RECORD,,