wrfrun 0.1.7__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 (46) hide show
  1. wrfrun/__init__.py +3 -0
  2. wrfrun/core/__init__.py +5 -0
  3. wrfrun/core/base.py +680 -0
  4. wrfrun/core/config.py +717 -0
  5. wrfrun/core/error.py +80 -0
  6. wrfrun/core/replay.py +113 -0
  7. wrfrun/core/server.py +212 -0
  8. wrfrun/data.py +418 -0
  9. wrfrun/extension/__init__.py +1 -0
  10. wrfrun/extension/littler/__init__.py +1 -0
  11. wrfrun/extension/littler/utils.py +599 -0
  12. wrfrun/extension/utils.py +66 -0
  13. wrfrun/model/__init__.py +7 -0
  14. wrfrun/model/base.py +14 -0
  15. wrfrun/model/plot.py +54 -0
  16. wrfrun/model/utils.py +34 -0
  17. wrfrun/model/wrf/__init__.py +6 -0
  18. wrfrun/model/wrf/_metgrid.py +71 -0
  19. wrfrun/model/wrf/_ndown.py +39 -0
  20. wrfrun/model/wrf/core.py +805 -0
  21. wrfrun/model/wrf/exec_wrap.py +101 -0
  22. wrfrun/model/wrf/geodata.py +301 -0
  23. wrfrun/model/wrf/namelist.py +377 -0
  24. wrfrun/model/wrf/scheme.py +311 -0
  25. wrfrun/model/wrf/vtable.py +65 -0
  26. wrfrun/pbs.py +86 -0
  27. wrfrun/plot/__init__.py +1 -0
  28. wrfrun/plot/wps.py +188 -0
  29. wrfrun/res/__init__.py +22 -0
  30. wrfrun/res/config.toml.template +136 -0
  31. wrfrun/res/extension/plotgrids.ncl +216 -0
  32. wrfrun/res/job_scheduler/pbs.template +6 -0
  33. wrfrun/res/job_scheduler/slurm.template +6 -0
  34. wrfrun/res/namelist/namelist.input.da_wrfvar.template +261 -0
  35. wrfrun/res/namelist/namelist.input.dfi.template +260 -0
  36. wrfrun/res/namelist/namelist.input.real.template +256 -0
  37. wrfrun/res/namelist/namelist.input.wrf.template +256 -0
  38. wrfrun/res/namelist/namelist.wps.template +44 -0
  39. wrfrun/res/namelist/parame.in.template +11 -0
  40. wrfrun/res/run.sh.template +16 -0
  41. wrfrun/run.py +264 -0
  42. wrfrun/utils.py +257 -0
  43. wrfrun/workspace.py +88 -0
  44. wrfrun-0.1.7.dist-info/METADATA +67 -0
  45. wrfrun-0.1.7.dist-info/RECORD +46 -0
  46. wrfrun-0.1.7.dist-info/WHEEL +4 -0
@@ -0,0 +1,256 @@
1
+ &time_control
2
+ run_days = 0
3
+ run_hours = 72
4
+ run_minutes = 0
5
+ run_seconds = 0
6
+ start_year = 2022, 2022, 2022
7
+ start_month = 5, 5, 5
8
+ start_day = 19, 19, 19
9
+ start_hour = 18, 18, 18
10
+ start_minute = 0, 0, 0
11
+ start_second = 0, 0, 0
12
+ end_year = 2022, 2022, 2022
13
+ end_month = 5, 5, 5
14
+ end_day = 22, 22, 22
15
+ end_hour = 18, 18, 18
16
+ end_minute = 0, 0, 0
17
+ end_second = 0, 0, 0
18
+ interval_seconds = 10800
19
+ input_from_file = .true., .true., .true.
20
+ fine_input_stream = 0, 0, 2
21
+ history_interval = 180, 180, 60
22
+ frames_per_outfile = 1000, 1000, 1000
23
+ history_outname = 'wrfout_d<domain>_<date>'
24
+ restart = .false.
25
+ restart_interval = 5000
26
+ override_restart_timers = .false.
27
+ io_form_history = 2
28
+ io_form_restart = 2
29
+ io_form_input = 2
30
+ io_form_boundary = 2
31
+ io_form_auxinput4 = 2
32
+ io_form_auxinput2 = 2
33
+ debug_level = 0
34
+ auxinput1_inname = './met_em.d<domain>.<date>'
35
+ auxinput4_inname = 'wrflowinp_d<domain>'
36
+ auxinput4_interval = 180, 180, 180
37
+ inputout_interval = 180
38
+ input_outname = 'wrfvar_d<domain>_<date>'
39
+ adjust_output_times = .true.
40
+ /
41
+
42
+ &domains
43
+ time_step = 120
44
+ time_step_fract_num = 0
45
+ time_step_fract_den = 1
46
+ max_dom = 2
47
+ time_step_dfi = 0
48
+ s_we = 1, 1, 1
49
+ e_we = 110, 151, 133
50
+ s_sn = 1, 1, 1
51
+ e_sn = 120, 181, 133
52
+ s_vert = 1, 1, 1
53
+ e_vert = 44, 44, 57
54
+ num_metgrid_levels = 38
55
+ num_metgrid_soil_levels = 3
56
+ p_top_requested = 5000
57
+ vert_refine_fact = 1
58
+ interp_theta = .false.
59
+ hypsometric_opt = 2
60
+ interp_type = 2
61
+ extrap_type = 2
62
+ t_extrap_type = 2
63
+ lowest_lev_from_sfc = .false.
64
+ force_sfc_in_vinterp = 1
65
+ use_surface = .true.
66
+ dx = 30000, 10000, 3333.333
67
+ dy = 30000, 10000, 3333.333
68
+ grid_id = 1, 2, 3
69
+ parent_id = 1, 1, 2
70
+ i_parent_start = 1, 35, 40
71
+ j_parent_start = 1, 34, 40
72
+ parent_grid_ratio = 1, 3, 3
73
+ parent_time_step_ratio = 1, 3, 4
74
+ feedback = 1
75
+ smooth_option = 2
76
+ nproc_x = -1
77
+ nproc_y = -1
78
+ numtiles = 6
79
+ use_adaptive_time_step = .false.
80
+ step_to_output_time = .true.
81
+ target_cfl = 1.1, 1.1, 1.1
82
+ max_step_increase_pct = 5, 51, 51
83
+ starting_time_step = 120, 40, 10
84
+ max_time_step = 240, 80, 20
85
+ min_time_step = 60, 20, 10
86
+ adaptation_domain = 1
87
+ /
88
+
89
+ &dfi_control
90
+ dfi_opt = 0
91
+ dfi_nfilter = 7
92
+ dfi_write_filtered_input = .true.
93
+ dfi_write_dfi_history = .false.
94
+ dfi_cutoff_seconds = 3600
95
+ dfi_time_dim = 9000
96
+ dfi_bckstop_year = 9991
97
+ dfi_bckstop_month = 9992
98
+ dfi_bckstop_day = 9993
99
+ dfi_bckstop_hour = 9994
100
+ dfi_bckstop_minute = 0
101
+ dfi_bckstop_second = 0
102
+ dfi_fwdstop_year = 8881
103
+ dfi_fwdstop_month = 8882
104
+ dfi_fwdstop_day = 8883
105
+ dfi_fwdstop_hour = 8884
106
+ dfi_fwdstop_minute = 30
107
+ dfi_fwdstop_second = 0
108
+ /
109
+
110
+ &physics
111
+ chem_opt = 0
112
+ mp_physics = 2, 2, 2
113
+ progn = 0, 0, 0
114
+ mp_zero_out = 2
115
+ mp_zero_out_thresh = 1e-08
116
+ do_radar_ref = 1
117
+ gsfcgce_hail = 0
118
+ gsfcgce_2ice = 0
119
+ no_mp_heating = 0
120
+ ra_lw_physics = 4, 4, 4
121
+ ra_sw_physics = 4, 4, 4
122
+ radt = 15, 15, 10
123
+ sf_sfclay_physics = 1, 1, 1
124
+ iz0tlnd = 1
125
+ sf_surface_physics = 2, 2, 2
126
+ sf_urban_physics = 1, 1, 1
127
+ bl_pbl_physics = 1, 1, 1
128
+ bl_mynn_tkeadvect = .true., .true., .true.
129
+ ysu_topdown_pblmix = 1
130
+ topo_wind = 1
131
+ bldt = 0, 0, 0
132
+ opt_thcnd = 2
133
+ grav_settling = 2, 2, 2
134
+ cu_physics = 1, 1, 0
135
+ ishallow = 0
136
+ cudt = 0, 0, 0
137
+ kfeta_trigger = 1
138
+ cu_rad_feedback = .true., .true., .true.
139
+ cugd_avedx = 1
140
+ isfflx = 1
141
+ ifsnow = 0
142
+ icloud = 3
143
+ surface_input_source = 1
144
+ num_land_cat = 21
145
+ num_soil_cat = 16
146
+ usemonalb = .true.
147
+ rdlai2d = .true.
148
+ sst_update = 1
149
+ num_soil_layers = 4
150
+ maxiens = 1
151
+ maxens = 3
152
+ maxens2 = 3
153
+ maxens3 = 16
154
+ ensdim = 144
155
+ slope_rad = 1
156
+ topo_shading = 1
157
+ shadlen = 25000.0
158
+ sf_ocean_physics = 0
159
+ oml_hml0 = 50
160
+ oml_gamma = 0.14
161
+ isftcflx = 0
162
+ fractional_seaice = 0
163
+ /
164
+
165
+ &fdda
166
+ obs_nudge_opt = 0, 0, 0
167
+ max_obs = 36000
168
+ fdda_start = 360.0, 360.0, 360.0
169
+ fdda_end = 99999.0, 99999.0, 99999.0
170
+ obs_nudge_wind = 1, 1, 1
171
+ obs_coef_wind = 0.0004, 0.0004, 0.0004
172
+ obs_nudge_temp = 1, 1, 1
173
+ obs_coef_temp = 0.0004, 0.0004, 0.0004
174
+ obs_nudge_mois = 1, 1, 1
175
+ obs_coef_mois = 2e-05, 2e-05, 2e-05
176
+ obs_rinxy = 240.0, 60.0, 180.0
177
+ obs_rinsig = 0.1
178
+ obs_twindo = 0.666667
179
+ obs_npfi = 10
180
+ obs_ionf = 2
181
+ obs_idynin = 0
182
+ obs_dtramp = 40.0
183
+ obs_ipf_errob = .true.
184
+ obs_ipf_nudob = .true.
185
+ obs_ipf_in4dob = .true.
186
+ grid_fdda = 0, 0
187
+ gfdda_inname = 'wrffdda_d<domain>'
188
+ gfdda_end_h = 72, 72
189
+ io_form_gfdda = 2
190
+ fgdt = 0, 0
191
+ if_no_pbl_nudging_uv = 0, 0
192
+ if_no_pbl_nudging_t = 1, 1
193
+ if_no_pbl_nudging_q = 1, 1
194
+ guv = 0.0004, 0.0004
195
+ gt = 0.0004, 0.0004
196
+ gq = 0.0004, 0.0004
197
+ if_ramping = 0
198
+ dtramp_min = 60
199
+ /
200
+
201
+ &dynamics
202
+ rk_ord = 3
203
+ w_damping = 1
204
+ diff_opt = 2
205
+ km_opt = 4
206
+ diff_6th_opt = 2, 2, 2
207
+ diff_6th_factor = 0.12, 0.12, 0.12
208
+ use_theta_m = 1
209
+ use_q_diabatic = 1
210
+ base_temp = 290.0
211
+ use_baseparam_fr_nml = .true.
212
+ damp_opt = 3
213
+ zdamp = 5000.0, 5000.0, 5000.0
214
+ dampcoef = 0.2, 0.2, 0.2
215
+ khdif = 0, 0, 0
216
+ kvdif = 0, 0, 0
217
+ non_hydrostatic = .true., .true., .true.
218
+ use_input_w = .true.
219
+ moist_adv_opt = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
220
+ moist_adv_dfi_opt = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
221
+ scalar_adv_opt = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
222
+ chem_adv_opt = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
223
+ tracer_adv_opt = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
224
+ tke_adv_opt = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
225
+ gwd_opt = 0
226
+ /
227
+
228
+ &bdy_control
229
+ spec_bdy_width = 5
230
+ spec_zone = 1
231
+ relax_zone = 4
232
+ specified = .true., .false., .false.
233
+ nested = .false., .true., .true.
234
+ constant_bc = .false.
235
+ have_bcs_moist = .false.
236
+ have_bcs_scalar = .false.
237
+ /
238
+
239
+ &tc
240
+ insert_bogus_storm = .false.
241
+ remove_storm = .false.
242
+ num_storm = 1
243
+ latc_loc = 25.0
244
+ lonc_loc = 127.0
245
+ vmax_meters_per_second = 60.0
246
+ rmax = 60000.0
247
+ vmax_ratio = 0.85
248
+ /
249
+
250
+ &grib2
251
+ /
252
+
253
+ &namelist_quilt
254
+ nio_tasks_per_group = 0
255
+ nio_groups = 1
256
+ /
@@ -0,0 +1,44 @@
1
+ &share
2
+ wrf_core = 'ARW'
3
+ max_dom = 2
4
+ start_date = '2022-05-19_15:00:00', '2022-05-19_15:00:00', '2022-05-19_15:00:00'
5
+ end_date = '2022-05-22_18:00:00', '2022-05-22_18:00:00', '2022-05-22_18:00:00'
6
+ interval_seconds = 10800
7
+ io_form_geogrid = 2
8
+ /
9
+
10
+ &geogrid
11
+ parent_id = 1, 1, 2
12
+ parent_grid_ratio = 1, 3, 3
13
+ i_parent_start = 1, 35, 40
14
+ j_parent_start = 1, 34, 40
15
+ e_we = 110, 151, 133
16
+ e_sn = 120, 181, 133
17
+ geog_data_res = '10m', '2m', '30s'
18
+ dx = 30000
19
+ dy = 30000
20
+ map_proj = 'lambert'
21
+ ref_lat = 36.0
22
+ ref_lon = 123.0
23
+ truelat1 = 20.0
24
+ truelat2 = 50.0
25
+ stand_lon = 123.0
26
+ geog_data_path = ''
27
+ /
28
+
29
+ &ungrib
30
+ out_format = 'WPS'
31
+ prefix = './outputs/FILE'
32
+ /
33
+
34
+ &metgrid
35
+ fg_name = './outputs/FILE'
36
+ process_only_bdy = 0
37
+ io_form_metgrid = 2
38
+ opt_output_from_metgrid_path = './'
39
+ /
40
+
41
+ &mod_levs
42
+ press_pa = 201300, 200100, 100000, 92500, 85000, 70000, 60000, 50000,
43
+ 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000
44
+ /
@@ -0,0 +1,11 @@
1
+ &control_param
2
+ da_file = './wrfvar_output'
3
+ wrf_bdy_file = './wrfbdy_d01'
4
+ wrf_input = './wrfinput_d01_bc'
5
+ domain_id = 1
6
+ debug = .true.
7
+ update_lateral_bdy = .true.
8
+ update_low_bdy = .false.
9
+ update_lsm = .false.
10
+ iswater = 16
11
+ /
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ #PBS -q batch
3
+ ##PBS -q odasc
4
+ #PBS -N py-wrfrun
5
+ #PBS -o {STDOUT_LOG_PATH}
6
+ #PBS -e {STDERR_LOG_PATH}
7
+ #PBS -l nodes={NODE_NUM}:ppn={CORE_NUM}
8
+ #PBS -l walltime=9999:00:00
9
+
10
+ ulimit -s unlimited
11
+
12
+ {ENV_SETTINGS}
13
+
14
+ cd {WORK_PATH}
15
+
16
+ {WORK_COMMAND}
wrfrun/run.py ADDED
@@ -0,0 +1,264 @@
1
+ """
2
+ ``wrfrun.run`` module.
3
+ """
4
+
5
+ import sys
6
+ import threading
7
+ from os.path import abspath, dirname, exists
8
+ from typing import Optional, Tuple, Union
9
+
10
+ from .core import ExecConfigRecorder, WRFRUNConfig, WRFRunBasicError, WRFRunServer, WRFRunServerHandler, replay_config_generator, stop_server
11
+ from .data import prepare_wps_input_data
12
+ from .model import clear_model_logs, plot_domain_area
13
+ from .pbs import in_pbs, prepare_pbs_script
14
+ from .utils import call_subprocess, logger, logger_add_file_handler
15
+ from .workspace import prepare_workspace
16
+
17
+
18
+ def confirm_model_area():
19
+ """
20
+ Ask user to check domain area.
21
+
22
+ """
23
+ plot_domain_area()
24
+
25
+ if not in_pbs():
26
+ # ask user
27
+ logger.warning(f"Check the domain image, is it right?")
28
+ answer = input("Is it right? [y/N]: ")
29
+
30
+ answer = answer.lower()
31
+
32
+ if answer not in ["y", "yes"]:
33
+ logger.error(f"Change your domain setting and run again")
34
+ exit(1)
35
+
36
+
37
+ class WRFRun:
38
+ """
39
+ ``WRFRun`` is a context class to use all functions in ``wrfrun`` package.
40
+ """
41
+ _instance = None
42
+ _initialized = False
43
+
44
+ def __init__(self, config_file: str, init_workspace=True, start_server=False, pbs_mode=False, prepare_wps_data=False, wps_data_area: Optional[Tuple[int, int, int, int]] = None):
45
+ """
46
+ WRFRun, a context class to achieve some goals before and after running WRF, like save a copy of config file, start and close WRFRunServer.
47
+
48
+ :param config_file: ``wrfrun`` config file's path.
49
+ :param init_workspace: If True, clean old files in workspace and re-create it.
50
+ :param start_server: Whether to start WRFRunServer, defaults to True.
51
+ :param pbs_mode: If commit this task to the PBS system, defaults to True.
52
+ :param prepare_wps_data: If True, download input datas for WPS first.
53
+ :param wps_data_area: If ``prepare_wps_data==True``, you need to give the area range of input data so download function can download data from ERA5.
54
+ :return:
55
+ """
56
+ if self._initialized:
57
+ return
58
+
59
+ # variables for running WRFRunServer
60
+ self._start_server = start_server
61
+ self._wrfrun_server: Union[WRFRunServer, None] = None
62
+ self._wrfrun_server_thread: Union[threading.Thread, None] = None
63
+ self._ip = ""
64
+ self._port = -1
65
+
66
+ self._pbs_mode = pbs_mode
67
+ self._init_workspace = init_workspace
68
+ self._prepare_wps_data = prepare_wps_data
69
+ self._wps_data_area = wps_data_area
70
+ self._entry_file_path = abspath(sys.argv[0])
71
+ self._entry_file_dir_path = dirname(self._entry_file_path)
72
+ self._replay_configs = None
73
+
74
+ # make sure we can read the config file, because sometimes the user may run the Python script in a different path.
75
+ abs_config_path = f"{self._entry_file_dir_path}/{config_file}"
76
+ WRFRUNConfig.load_wrfrun_config(abs_config_path)
77
+
78
+ self._record_output_path = None
79
+ self._record_include_data = False
80
+ self._WRFRUNReplay = ExecConfigRecorder
81
+
82
+ self._initialized = True
83
+
84
+ def __new__(cls, *args, **kwargs):
85
+ if cls._instance is None:
86
+ cls._instance = super().__new__(cls)
87
+
88
+ return cls._instance
89
+
90
+ def __enter__(self):
91
+ # check workspace
92
+ check_list = [WRFRUNConfig.WPS_WORK_PATH, WRFRUNConfig.WRF_WORK_PATH, WRFRUNConfig.WRFDA_WORK_PATH]
93
+ check_list = [WRFRUNConfig.parse_resource_uri(x) for x in check_list]
94
+ for _path in check_list:
95
+ if not exists(_path) and not self._init_workspace:
96
+ logger.info(f"Force re-create workspace because it is broken.")
97
+ self._init_workspace = True
98
+ break
99
+
100
+ # here is the condition we need to initialize workspace:
101
+ # 1. pbs_mode = True and init_workspace = True, do prepare_workspace before committing the task to the PBS system.
102
+ # 2. pbs_mode = False and init_workspace = True, do prepare_workspace.
103
+ if self._pbs_mode and not in_pbs():
104
+ if self._init_workspace:
105
+ prepare_workspace()
106
+
107
+ # ask user before commit the task
108
+ confirm_model_area()
109
+
110
+ prepare_pbs_script(self._entry_file_path)
111
+
112
+ call_subprocess(["qsub", f"{self._entry_file_dir_path}/run.sh"])
113
+ logger.info(f"Work has been submit to PBS system")
114
+ exit(0)
115
+
116
+ elif not self._pbs_mode:
117
+ if self._init_workspace:
118
+ prepare_workspace()
119
+
120
+ confirm_model_area()
121
+
122
+ # save a copy of config to the output path
123
+ WRFRUNConfig.save_wrfrun_config(f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/config.toml")
124
+
125
+ # check if we need to start a server
126
+ if self._start_server:
127
+ # start server
128
+ self._start_wrfrun_server()
129
+
130
+ # change status
131
+ WRFRUNConfig.set_wrfrun_context(True)
132
+
133
+ logger_add_file_handler(WRFRUNConfig.get_log_path())
134
+
135
+ if self._prepare_wps_data:
136
+ if self._wps_data_area is None:
137
+ logger.error(f"If you want wrfrun preparing data, you need to give `wps_data_area`")
138
+ raise ValueError(f"If you want wrfrun preparing data, you need to give `wps_data_area`")
139
+ else:
140
+ prepare_wps_input_data(self._wps_data_area)
141
+
142
+ logger.info(r"Enter wrfrun context")
143
+
144
+ return self
145
+
146
+ def __exit__(self, exc_type, exc_val, exc_tb):
147
+ # stop thread if needed
148
+ if self._start_server:
149
+ stop_server(self._ip, self._port) # type: ignore
150
+
151
+ if exc_type is None and WRFRUNConfig.IS_RECORDING:
152
+ self._WRFRUNReplay.export_replay_file()
153
+ self._WRFRUNReplay.clear_records()
154
+
155
+ # change status
156
+ WRFRUNConfig.set_wrfrun_context(False)
157
+
158
+ clear_model_logs()
159
+
160
+ logger.info(r"Exit wrfrun context")
161
+
162
+ def _start_wrfrun_server(self):
163
+ """
164
+ Start a WRFRunServer.
165
+ """
166
+ # read ip and port settings from config
167
+ socket_ip, socket_port = WRFRUNConfig.get_socket_server_config()
168
+
169
+ # get simulate settings
170
+ start_date = WRFRUNConfig.get_model_config("wrf")["time"]["start_date"]
171
+ end_date = WRFRUNConfig.get_model_config("wrf")["time"]["end_date"]
172
+
173
+ start_date = start_date[0] if isinstance(start_date, list) else start_date
174
+ end_date = end_date[0] if isinstance(end_date, list) else end_date
175
+
176
+ # calculate simulate seconds
177
+ time_delta = end_date - start_date
178
+ simulate_seconds = time_delta.days * 24 * 60 * 60 + time_delta.seconds
179
+
180
+ # init server
181
+ self._wrfrun_server = WRFRunServer(
182
+ start_date, simulate_seconds, (socket_ip, socket_port),
183
+ WRFRunServerHandler
184
+ )
185
+
186
+ # get ip and port from instance, because the port may change
187
+ self._ip, self._port = self._wrfrun_server.server_address
188
+
189
+ logger.info(f"Start socket server on {self._ip}:{self._port}")
190
+
191
+ # start server thread
192
+ self._wrfrun_server_thread = threading.Thread(
193
+ target=self._wrfrun_server.serve_forever
194
+ )
195
+ self._wrfrun_server_thread.daemon = True
196
+ self._wrfrun_server_thread.start()
197
+
198
+ def record_simulation(self, output_path: str, include_data=False):
199
+ """
200
+ Change settings, so wrfrun can record simulation and generate a replay file.
201
+
202
+ :param output_path: Output file path.
203
+ :type output_path: str
204
+ :param include_data: If includes data.
205
+ :type include_data: bool
206
+ :return:
207
+ :rtype:
208
+ """
209
+ self._record_output_path = output_path
210
+ self._record_include_data = include_data
211
+ self._WRFRUNReplay = self._WRFRUNReplay.reinit(save_path=output_path, include_data=include_data)
212
+
213
+ def replay_simulation(self, replay_file: str):
214
+ """
215
+ Replay the simulation without any changes.
216
+
217
+ :param replay_file:
218
+ :type replay_file:
219
+ :return:
220
+ :rtype:
221
+ """
222
+ WRFRUNConfig.check_wrfrun_context(True)
223
+
224
+ if self._replay_configs is not None:
225
+ del self._replay_configs
226
+
227
+ self._replay_configs = replay_config_generator(replay_file)
228
+
229
+ WRFRUNConfig.IS_IN_REPLAY = True
230
+
231
+ try:
232
+ for _, executable in self._replay_configs:
233
+ executable.replay()
234
+
235
+ except WRFRunBasicError:
236
+ logger.error("Failed to replay the simulation")
237
+
238
+ WRFRUNConfig.IS_IN_REPLAY = False
239
+
240
+ def replay_executables(self, replay_file: str):
241
+ """
242
+ Replay the simulation without any changes.
243
+
244
+ :param replay_file:
245
+ :type replay_file:
246
+ :return:
247
+ :rtype:
248
+ """
249
+ WRFRUNConfig.check_wrfrun_context(True)
250
+
251
+ if self._replay_configs is not None:
252
+ del self._replay_configs
253
+
254
+ self._replay_configs = replay_config_generator(replay_file)
255
+
256
+ WRFRUNConfig.IS_IN_REPLAY = True
257
+
258
+ for name, executable in self._replay_configs:
259
+ yield name, executable
260
+
261
+ WRFRUNConfig.IS_IN_REPLAY = False
262
+
263
+
264
+ __all__ = ["WRFRun"]