def get_total_volume(soln_dir: os.PathLike, frame_bg: int, frame_ed: int, n_levels: int): """Get total volumes at AMR levels. Arguments --------- soln_dir : pathlike Path to where the solution files are. frame_bg, frame_ed : int Begining and end frame numbers. n_levels : int Total number of AMR levels. Returns ------- A list of of shape (n_frames, n_levels). """ soln_dir = pathlib.Path(soln_dir).expanduser().resolve() ans = [[0. for _ in range(n_levels)] for _ in range(frame_bg, frame_ed)] for ifno, fno in enumerate(range(frame_bg, frame_ed)): # solution file of this time frame soln = pyclaw.Solution() soln.read(fno, str(soln_dir), file_format="binary", read_aux=False) # search through AMR grid patches, if found desired dx & dy at the level, quit for state in soln.states: p = state.patch # pylint: disable=invalid-name ans[ifno][p.level - 1] += (state.q[0].sum() * p.delta[0] * p.delta[1]) return ans
def get_topo_max(soln_dir: os.PathLike, frame_bg: int, frame_ed: int, level: int): """Get the maximum elevation during runtime among the time frames at a specific AMR level. Arguments --------- soln_dir : pathlike Path to where the solution files are. frame_bg, frame_ed : int Begining and end frame numbers. level : int The level of AMR to provess. Returns ------- vmax : float """ soln_dir = pathlib.Path(soln_dir).expanduser().resolve() vmax = -float("inf") for fno in range(frame_bg, frame_ed): # aux and solution file of this time frame aux = soln_dir.joinpath("fort.a" + "{}".format(fno).zfill(4)).is_file() if not aux: # this time frame does not contain runtime topo data continue soln = pyclaw.Solution() soln.read(fno, str(soln_dir), file_format="binary", read_aux=True) # search through AMR grid patches in this solution for state in soln.states: if state.patch.level != level: continue vmax = max(vmax, state.aux[0].max()) if vmax == -float("inf"): raise _misc.NoFrameDataError("No AUX found in frames {} to {}.".format( frame_bg, frame_ed)) return vmax
def get_soln_extent(soln_dir: os.PathLike, frame_bg: int, frame_ed: int, level: int): """Get the bounding box of the results of all time frames at a specific AMR level. Arguments --------- soln_dir : pathlike Path to where the solution files are. frame_bg, frame_ed : int Begining and end frame numbers. level : int The level of AMR to provess. Returns ------- extent : tuple/list [xmin, ymin, xmax, ymax] (i.e., [west, south, east, north]) """ soln_dir = pathlib.Path(soln_dir).expanduser().resolve() extent = [float("inf"), float("inf"), -float("inf"), -float("inf")] for fno in range(frame_bg, frame_ed): # aux and solution file of this time frame aux = soln_dir.joinpath("fort.a" + "{}".format(fno).zfill(4)) soln = pyclaw.Solution() soln.read(fno, str(soln_dir), file_format="binary", read_aux=aux.is_file()) # search through AMR grid patches in this solution for state in soln.states: if state.patch.level != level: continue extent[0] = min(extent[0], state.patch.lower_global[0]) extent[1] = min(extent[1], state.patch.lower_global[1]) extent[2] = max(extent[2], state.patch.upper_global[0]) extent[3] = max(extent[3], state.patch.upper_global[1]) return extent
def get_soln_max(soln_dir: os.PathLike, frame_bg: int, frame_ed: int, level: int): """Get the maximum depth of the results of all time frames at a specific AMR level. Arguments --------- soln_dir : pathlike Path to where the solution files are. frame_bg, frame_ed : int Begining and end frame numbers. level : int The level of AMR to provess. Returns ------- vmax : float """ soln_dir = pathlib.Path(soln_dir).expanduser().resolve() vmax = -float("inf") for fno in range(frame_bg, frame_ed): # aux and solution file of this time frame aux = soln_dir.joinpath("fort.a" + "{}".format(fno).zfill(4)) soln = pyclaw.Solution() soln.read(fno, str(soln_dir), file_format="binary", read_aux=aux.is_file()) # search through AMR grid patches in this solution for state in soln.states: if state.patch.level != level: continue vmax = max(vmax, state.q[0].max()) return vmax
def get_soln_res(soln_dir: os.PathLike, frame_bg: int, frame_ed: int, level: int): """Get the resolution of the grid at a specific AMR level. Arguments --------- soln_dir : pathlike Path to where the solution files are. frame_bg, frame_ed : int Begining and end frame numbers. level : int The level of AMR to provess. Returns ------- dx, dy : float Cell size at x and y direction. """ soln_dir = pathlib.Path(soln_dir).expanduser().resolve() for fno in range(frame_bg, frame_ed): # aux and solution file of this time frame aux = soln_dir.joinpath("fort.a" + "{}".format(fno).zfill(4)) soln = pyclaw.Solution() soln.read(fno, str(soln_dir), file_format="binary", read_aux=aux.is_file()) # search through AMR grid patches, if found desired dx & dy at the level, quit for state in soln.states: if state.patch.level == level: return state.patch.delta raise _misc.AMRLevelError("No solutions has AMR level {}".format(level))
def plot_soln_frames_on_sat(args: argparse.Namespace, satellite_img: numpy.ndarray, satellite_extent: Tuple[float, float, float, float]): """Plot solution frames on a satellite image. Currently, this function is supposed to be called by `plot_depth` with multiprocessing. Argumenst --------- args : argparse.Namespace CMD argument parsed by `argparse`. satellite_img : numpy.ndarray, The RBG data for the satellite image. satellite_extent : Tuple[float, float, float, float]): The extent of the satellite image. Returns ------- Execution code. 0 for success. """ # plot fig, axes = matplotlib.pyplot.subplots() axes.imshow(satellite_img, extent=[ satellite_extent[0], satellite_extent[2], satellite_extent[1], satellite_extent[3] ]) for fno in range(args.frame_bg, args.frame_ed): print("Processing frame {} by PID {}".format(fno, os.getpid())) # read in solution data soln = pyclaw.Solution() soln.read(fno, str(args.soln_dir), file_format="binary", read_aux=args.soln_dir.joinpath( "fort.a" + "{}".format(fno).zfill(4)).is_file()) axes, imgs, _, _ = plot_soln_frame_on_ax(axes, soln, args.level, [args.cmin, args.cmax], args.dry_tol, cmap=args.cmap, border=args.border) axes.set_xlim(satellite_extent[0], satellite_extent[2]) axes.set_ylim(satellite_extent[1], satellite_extent[3]) fig.suptitle("T = {} sec".format(soln.state.t)) # title fig.savefig(args.dest_dir.joinpath( "frame{:05d}.png".format(fno))) # save # clear artists while True: try: img = imgs.pop() img.remove() del img except IndexError: break print("PID {} done processing frames {} - {}".format( os.getpid(), args.frame_bg, args.frame_ed)) return 0
def plot_soln_frames(args: argparse.Namespace): """Plot solution frames. Currently, this function is supposed to be called by `plot_depth` with multiprocessing. Argumenst --------- args : argparse.Namespace CMD argument parsed by `argparse`. Returns ------- Execution code. 0 for success. """ # plot if args.no_topo: fig, axes = matplotlib.pyplot.subplots( 1, 2, gridspec_kw={"width_ratios": [10, 1]}) else: fig, axes = matplotlib.pyplot.subplots( 1, 3, gridspec_kw={"width_ratios": [10, 1, 1]}) axes[0], _, cmap_t, cmscale_t = plot_topo_on_ax( axes[0], args.topofiles, args.colorize, extent=args.extent, degs=[args.topo_azdeg, args.topo_altdeg], clims=[args.topo_cmin, args.topo_cmax]) for fno in range(args.frame_bg, args.frame_ed): print("Processing frame {} by PID {}".format(fno, os.getpid())) # read in solution data soln = pyclaw.Solution() soln.read(fno, str(args.soln_dir), file_format="binary", read_aux=args.soln_dir.joinpath( "fort.a" + "{}".format(fno).zfill(4)).is_file()) axes[0], imgs, cmap_s, cmscale_s = plot_soln_frame_on_ax( axes[0], soln, args.level, [args.cmin, args.cmax], args.dry_tol, cmap=args.cmap, border=args.border) axes[0].set_xlim(args.extent[0], args.extent[2]) axes[0].set_ylim(args.extent[1], args.extent[3]) # solution depth colorbar fig.colorbar(matplotlib.cm.ScalarMappable(cmscale_s, cmap_s), cax=axes[1]) if not args.no_topo: # topography colorbar fig.colorbar(matplotlib.cm.ScalarMappable(cmscale_t, cmap_t), cax=axes[2]) fig.suptitle("T = {} sec".format(soln.state.t)) # title fig.savefig(args.dest_dir.joinpath( "frame{:05d}.png".format(fno))) # save # clear artists while True: try: img = imgs.pop() img.remove() del img except IndexError: break print("PID {} done processing frames {} - {}".format( os.getpid(), args.frame_bg, args.frame_ed)) return 0
def write_soln_to_nc( nc_file: os.PathLike, soln_dir: os.PathLike, frame_bg: int, frame_ed: int, level: int, dry_tol: float, extent: Tuple[float, float, float, float], res: float, nodata: int ): """Write solutions of time frames to band data of an existing NetCDF raster file. This function will first interpolate the simulation results onto a new uniform grid/raster with the giiven `extent` and `res` (resolution), and then it writes the solutions on this uniform grid to the NetCDF raster file. Arguments --------- nc_file : os.PathLike The path to the target NetCDF raster file. soln_dir : os.PathLike The folder where Clawutil's solution files are. frame_bg, frame_ed : int The beginning and end frame numbers. The end frame number should be one larger than the real end because it will be used in `range` funtion directly. level : int The target AMR level. dry_tol : float Depth below `dry_tol` will be treated as dry cells and have value `nodata`. extent : Tuple[float, float, float, float] The extent/bound of solution raster. The format is [xmin, ymin, xmax, ymax]. res : float The resolution of the output nodata : int The value indicating a cell being masked. """ # pylint: disable=too-many-arguments # open the provided NC file and get the root group root = netCDF4.Dataset( # pylint: disable=no-member filename=nc_file, mode="r+", encoding="utf-8", format="NETCDF4") print("Frame No. ", end="") for band, fno in enumerate(range(frame_bg, frame_ed)): print("..{}".format(fno), end="") sys.stdout.flush() # determine whether to read aux aux = soln_dir.joinpath("fort.a"+"{}".format(fno).zfill(4)).is_file() # read in solution data soln = pyclaw.Solution() soln.read(fno, str(soln_dir), file_format="binary", read_aux=aux) # write the time root["time"][band] = soln.state.t try: # write the depth values root["depth"][band, :, :] = _postprocessing.calc.interpolate( soln, level, dry_tol, extent, res, nodata)[0] except _misc.NoWetCellError: root["depth"][band, :, :] = nodata print() root.close()