11from isodate
import parse_duration
14parser = argparse.ArgumentParser(
"yac_replay",
15 description=
"""Replay simulation from a dataset.
16The given files are loaded with `uxarray.open_dataset`.
17It is currently not supported to run this component in parallel.""")
18parser.add_argument(
"gridfile", type=str,
19 default=
"path to the gridfile")
20parser.add_argument(
"datafile", type=str,
21 default=
"path to the dataset")
22parser.add_argument(
"variables", type=str, nargs=
"+",
23 help=
"Variable names to be recorded")
24parser.add_argument(
"--compname", type=str, default=
"record",
25 help=
"Name for the yac component (default: record)")
26parser.add_argument(
"--gridname", type=str, default=
"record_grid",
27 help=
"Name for the yac grid (default: record_grid)")
28parser.add_argument(
"--log-level", default=logging.WARNING, type=
lambda x: getattr(logging, x.upper()),
29 help=
"Configure the logging level.")
30parser.add_argument(
"--coupling-config", type=str, default=
None,
31 help=
"If given the yac config is read with yac.read_config_yaml")
32parser.add_argument(
"--points", type=str, nargs=
"*", choices=(
"cell",
"edge",
"vertex"),
34 help=
"can be used to specify the entities on which the data should be recorded.")
36args = parser.parse_args()
37log_handler = logging.StreamHandler()
38log_handler.setFormatter(logging.Formatter(
"%(asctime)-10s %(name)-10s %(levelname)-8s %(message)s"))
39logging.basicConfig(level=args.log_level, handlers=[log_handler])
41logging.info(
"Instantiate yac")
44logging.info(f
"reading config file {args.coupling_config!r}")
46if args.coupling_config:
47 y.read_config_yaml(args.coupling_config)
49logging.info(f
"open dataset: {args.gridfile!r}, {args.datafile!r}")
51uxgrid = ux.open_grid(args.gridfile)
53logging.info(f
"define component: {args.compname}")
54comp = y.def_comp(args.compname)
59cell_to_edge = np.asarray(uxgrid.face_edge_connectivity).reshape((-1,), order=
"C")
60cell_to_edge = cell_to_edge[cell_to_edge != ux.INT_FILL_VALUE]
62logging.info(
"defining grid")
64 uxgrid.n_nodes_per_face,
65 np.deg2rad(uxgrid.node_lon),
66 np.deg2rad(uxgrid.node_lat),
67 cell_to_edge, uxgrid.edge_node_connectivity)
69cell_point_id = grid.def_points(yac.Location.CELL,
70 np.deg2rad(uxgrid.face_lon),
71 np.deg2rad(uxgrid.face_lat))
72edge_point_id = grid.def_points(yac.Location.EDGE,
73 np.deg2rad(uxgrid.edge_lon),
74 np.deg2rad(uxgrid.edge_lat))
75vertex_point_id = grid.def_points(yac.Location.CORNER,
76 np.deg2rad(uxgrid.node_lon),
77 np.deg2rad(uxgrid.node_lat))
79if len(args.points) == 1:
80 args.points = len(args.variables)*[args.points[0]]
81args.points = args.points
or len(args.variables)*[
"cell"]
82assert len(args.points) == len(args.variables),
"If points are speified it must be given once or the same number as variables"
84logging.info(
"calling sync_def")
88for varname
in args.variables:
89 assert y.get_field_role(args.compname, args.gridname, varname) == yac.ExchangeType.TARGET, \
90 f
"{varname!r} is not coupled to a target. Please define a coupling or remove it from the variables."
92start = np.datetime64(y.start_datetime)
93end = np.datetime64(y.end_datetime)
96first_source = y.get_field_source(args.compname, args.gridname, args.variables[0])
97dt = np.timedelta64(parse_duration(y.get_field_timestep(*first_source)))
99logging.info(f
"Timestep is {dt}")
102ds = ux.UxDataset(uxgrid=uxgrid)
103ds[
"time"] = np.arange(start, end+dt, dt)
105for varname, points
in zip(args.variables, args.points):
106 logging.info(f
"configuring {varname!r}")
107 source = y.get_field_source(args.compname, args.gridname, varname)
108 logging.info(f
"coupled to {source!r}")
109 assert dt == np.timedelta64(parse_duration(y.get_field_timestep(*source))), \
110 "Source fields of variables have incosistent timesteps"
111 collection_size = y.get_field_collection_size(*source)
112 logging.info(f
"collection size: {collection_size}")
113 if collection_size > 1:
114 zaxis = [f
"zaxis_{varname}"]
117 logging.info(f
"zaxis: {zaxis}")
118 spatial_dim, spatial_size, point_id = \
119 {
"cell": (
"n_face", uxgrid.n_face, cell_point_id),
120 "edge": (
"n_edge", uxgrid.n_edge, edge_point_id),
121 "vertex": (
"n_node", uxgrid.n_node, vertex_point_id)}[points]
122 data = np.nan*np.ones((len(ds[
"time"]), *(len(zaxis)*[collection_size]), spatial_size))
123 ds = ds.assign({varname:
124 ((
"time", *zaxis, spatial_dim), data)})
130 str(int(dt / np.timedelta64(1,
'ms'))), yac.TimeUnit.MILLISECOND),
134logging.info(
"calling enddef")
138 for field, var
in fields:
139 logging.info(f
"processing {field.name} at {field.datetime}")
140 t = np.datetime64(field.datetime)
141 t_idx = np.searchsorted(ds[
"time"], t)
142 assert ds[
"time"][t_idx] == t, f
"{t} not found in timeaxis"
143 data, info = field.get()
144 var.isel(time=t_idx).data[:] = data
145 logging.info(f
"info: {info!r}")
146 if info == yac.Action.GET_FOR_RESTART:
149ds.to_netcdf(args.datafile)
create(cls, str field_name, Component comp, points, collection_size, str timestep, TimeUnit timeunit, masks=None)
Initializies a YAC instance and provides further functionality.