@@ -46,8 +46,8 @@ def prepare_states(
46
46
47
47
# Process each file, concatenate with the next t-1 files
48
48
for i in range (len (files ) - n_states + 1 ):
49
- # Name as today's date
50
- out_filename = f"{ prefix } _{ os .path .basename (files [i + 1 ])} "
49
+ # Name as first forecasted date
50
+ out_filename = f"{ prefix } _{ os .path .basename (files [i + 2 ])} "
51
51
out_file = os .path .join (out_directory , out_filename )
52
52
53
53
if os .path .isfile (out_file ):
@@ -132,27 +132,22 @@ def prepare_states_with_boundary(
132
132
133
133
# Process each file, concatenate with the next t-1 files
134
134
for i in range (len (files ) - n_states + 1 ):
135
- today = os .path .basename (files [i + 1 ])
136
- out_filename = f"{ prefix } _{ today } "
135
+ forecast_date = os .path .basename (files [i + 2 ])
136
+ out_filename = f"{ prefix } _{ forecast_date } "
137
137
out_file = os .path .join (out_directory , out_filename )
138
138
139
- if os .path .isfile (out_file ):
140
- continue
141
-
142
139
# Stack analysis states
143
140
state_sequence = [np .load (files [i + j ]) for j in range (n_states )]
144
141
full_state = np .stack (state_sequence , axis = 0 )
145
142
print ("full state" , full_state .shape ) # (n_states, N_grid, d_features)
146
143
147
- forecast_file = files [i + 1 ].replace ("analysis" , "forecast" )
148
- forecast_data = np .load (forecast_file )
149
- forecast_len = forecast_data .shape [0 ]
144
+ forecast_file = files [i + 2 ].replace ("analysis" , "forecast" )
145
+ forecast_data = np .load (forecast_file )[2 :]
150
146
print (
151
147
"forecast before" , forecast_data .shape
152
148
) # (forecast_len, N_grid, d_features)
153
149
154
- assert n_states >= forecast_len , "n_states less than forecast length"
155
- extra_states = n_states - 1 - forecast_data .shape [0 ]
150
+ extra_states = 5
156
151
last_forecast_state = forecast_data [- 1 ]
157
152
repeated_forecast_states = np .repeat (
158
153
last_forecast_state [np .newaxis , ...], extra_states , axis = 0
@@ -162,21 +157,65 @@ def prepare_states_with_boundary(
162
157
)
163
158
print (
164
159
"forecast after" , forecast_data .shape
165
- ) # (n_states - 1 , N_grid, d_features)
160
+ ) # (n_states - 2 , N_grid, d_features)
166
161
167
162
# Concatenate preceding day analysis state with forecast data
168
163
forecast_data = np .concatenate (
169
- (state_sequence [:1 ], forecast_data ), axis = 0
164
+ (state_sequence [:2 ], forecast_data ), axis = 0
170
165
) # (n_states, N_grid, d_features)
171
166
172
167
full_state = (
173
168
full_state * (1 - border_mask ) + forecast_data * border_mask
174
169
)
175
170
176
- np .save (out_file , full_state )
171
+ np .save (out_file , full_state . astype ( np . float32 ) )
177
172
print (f"Saved states to: { out_file } " )
178
173
179
174
175
+ def prepare_forecast (in_directory , out_directory , prefix , start_date , end_date ):
176
+ """
177
+ Prepare forecast data by repeating the last state.
178
+ """
179
+ forecast_dir = in_directory
180
+
181
+ start_dt = datetime .strptime (start_date , "%Y-%m-%d" )
182
+ end_dt = datetime .strptime (end_date , "%Y-%m-%d" )
183
+
184
+ os .makedirs (out_directory , exist_ok = True )
185
+
186
+ # Get files sorted by date
187
+ forecast_files = sorted (
188
+ glob (os .path .join (forecast_dir , "*.npy" )),
189
+ key = lambda x : datetime .strptime (os .path .basename (x )[:8 ], "%Y%m%d" ),
190
+ )
191
+ forecast_files = [
192
+ f
193
+ for f in forecast_files
194
+ if start_dt
195
+ <= datetime .strptime (os .path .basename (f )[:8 ], "%Y%m%d" )
196
+ <= end_dt
197
+ ]
198
+
199
+ for forecast_file in forecast_files :
200
+ # Load the current forecast data
201
+ forecast_data = np .load (forecast_file )
202
+ print (forecast_data .shape )
203
+
204
+ last_forecast_state = forecast_data [- 1 ]
205
+ repeated_forecast_states = np .repeat (
206
+ last_forecast_state [np .newaxis , ...], repeats = 5 , axis = 0
207
+ )
208
+ forecast_data = np .concatenate (
209
+ [forecast_data , repeated_forecast_states ], axis = 0
210
+ )
211
+
212
+ # Save concatenated data
213
+ out_filename = f"{ prefix } _{ os .path .basename (forecast_file )} "
214
+ out_file = os .path .join (out_directory , out_filename )
215
+ np .save (out_file , forecast_data )
216
+ print (f"Saved forecast to: { out_file } " )
217
+
218
+
180
219
def prepare_forcing (in_directory , out_directory , prefix , start_date , end_date ):
181
220
"""
182
221
Prepare atmospheric forcing data from forecasts.
@@ -205,6 +244,14 @@ def prepare_forcing(in_directory, out_directory, prefix, start_date, end_date):
205
244
forecast_date = datetime .strptime (
206
245
os .path .basename (forecast_file )[:8 ], "%Y%m%d"
207
246
)
247
+
248
+ # Get files for the pre-preceding day
249
+ prepreceding_day_file = os .path .join (
250
+ forecast_dir ,
251
+ (forecast_date - timedelta (days = 2 )).strftime ("%Y%m%d" ) + ".npy" ,
252
+ )
253
+ prepreceding_day_data = np .load (prepreceding_day_file )[0 :1 ]
254
+
208
255
# Get files for the preceding day
209
256
preceding_day_file = os .path .join (
210
257
forecast_dir ,
@@ -217,12 +264,14 @@ def prepare_forcing(in_directory, out_directory, prefix, start_date, end_date):
217
264
218
265
print (preceding_day_data .shape , current_forecast_data .shape )
219
266
267
+ prepreceding_day_data = prepreceding_day_data [:, :, :4 ]
220
268
preceding_day_data = preceding_day_data [:, :, :4 ]
221
269
current_forecast_data = current_forecast_data [:, :, :4 ]
222
270
223
271
# Concatenate all data along the time axis
224
272
concatenated_forcing = np .concatenate (
225
- [preceding_day_data , current_forecast_data ], axis = 0
273
+ [prepreceding_day_data , preceding_day_data , current_forecast_data ],
274
+ axis = 0 ,
226
275
)
227
276
228
277
# Save concatenated data
@@ -303,7 +352,7 @@ def main():
303
352
args .start_date ,
304
353
args .end_date ,
305
354
)
306
- else :
355
+ elif args . data_dir . endswith ( "analysis" ) :
307
356
prepare_states_with_boundary (
308
357
args .data_dir ,
309
358
args .static_dir ,
@@ -313,6 +362,14 @@ def main():
313
362
args .start_date ,
314
363
args .end_date ,
315
364
)
365
+ else :
366
+ prepare_forecast (
367
+ args .data_dir ,
368
+ args .out_dir ,
369
+ args .prefix ,
370
+ args .start_date ,
371
+ args .end_date ,
372
+ )
316
373
else :
317
374
prepare_states (
318
375
args .data_dir ,
0 commit comments