7.3.4. IO Module
io module
Helper functions to load or write files
A note on naming conventions in the python IO interfaces as compared to the C implementation for reading/writing pfb files: +————————-+——————+———————+ | Description | Parflow C | Parflow Python | +————————-+——————+———————+ | Subgrid lengths | P, Q, R | p, q, r | | Subgrid indices | p, q, r | sg_p, sg_q, sg_r | | Size of the full grid | NX, NY, NZ | nx, ny, nz | | Size of a subgrid | nx, ny, nz | sg_nx, sg_ny, sg_nz | | Cell size of the grid | dx, dy, dz | dx, dy, dz | | Lower left index | ix, iy, iz | ix, iy, iz | +————————-+——————+———————+
- class parflow.tools.io.DataAccessor(run, selector=None)
Bases:
objectHelper for extracting numpy array from a given run
- __init__(run, selector=None)
Create DataAccessor from a Run instance
- clm_forcing(name)
- property clm_forcing_apcp
Precipitation rate [mm/s]
- property clm_forcing_dlwr
Downward Infa-Red or Long-Wave radiation [W/m2]
- property clm_forcing_dswr
Downward Visible or Short-Wave radiation [W/m2]
- property clm_forcing_press
Atmospheric Pressure [pa]
- property clm_forcing_spfh
Water-vapor specific humidity [kg/kg]
- property clm_forcing_temp
Air temperature [K]
- property clm_forcing_ugrd
West-to-East or U-component of wind [m/s]
- property clm_forcing_vgrd
South-to-North or V-component of wind [m/s]
- property clm_map_clay
- property clm_map_color
- clm_map_land_fraction(name)
- property clm_map_latitude
- property clm_map_longitude
- property clm_map_sand
- clm_output(field, layer=-1)
- property clm_output_diagnostics
- property clm_output_eflx_lh_tot
- property clm_output_eflx_lwrad_out
- property clm_output_eflx_sh_tot
- property clm_output_eflx_soil_grnd
- property clm_output_qflx_evap_grnd
- property clm_output_qflx_evap_soi
- property clm_output_qflx_evap_tot
- property clm_output_qflx_evap_veg
- property clm_output_qflx_infl
- property clm_output_qflx_top_soil
- property clm_output_qflx_tran_veg
- property clm_output_swe_out
- property clm_output_t_grnd
- property clm_output_variables
- property computed_permeability_x
- property computed_permeability_y
- property computed_permeability_z
- property computed_porosity
- property dx
- property dy
- property dz
- property elevation
- property et
- property forcing_time
- property mannings
- property mask
- overland_flow(flow_method='OverlandKinematic', epsilon=1e-05)
- overland_flow_grid(flow_method='OverlandKinematic', epsilon=1e-05)
- property pressure
- property pressure_boundary_conditions
- property pressure_initial_condition
- property process_id
- property saturation
- property selector
- property shape
- property slope_x
- property slope_y
- property specific_storage
- property subsurface_storage
- property surface_storage
- property time
- property times
- property wtd
- class parflow.tools.io.ParflowBinaryReader(file: str, precompute_subgrid_info: bool = True, p: int = None, q: int = None, r: int = None, header: Mapping[str, Number] = None, read_sg_info: bool = False)
Bases:
objectThe ParflowBinaryReader, unsurprisingly, provides functionality for reading parflow binary files. It is designed to separate the header reading and metadata from subgrids from the reading of the underlying subgrid data in an efficient and flexible way. The ParflowBinaryReader only ever stores state about the header and/or subgrid headers. When reading data it is immediately returned to the user in the form of a numpy array. The ParflowBinaryReader implements a simple Context Manager so it is recommended to use with the standard idiom:
:: with ParflowBinaryReader(file) as pfb:
data = pfb.read_all_subgrids()
- Parameters:
file – The pfb file to read
precompute_subgrid_info – Whether or not to precompute subgrid information. This defaults to
Truebut can be turned off for reading multiple pfb files to reduce the amount of IO overhead when reading a sequence of pfb files. This computes the subgrid offset bytes, subgrid locations, subgrid indices, subgrid shapes, as well as subgrid coordinates and chunk sizesp – The number of subgrids along the x dimension. This is an optional input, if it is not given we will try to precompute it.
q – The number of subgrids along the y dimension. This is an optional input, if it is not given we will try to precompute it.
r – The number of subgrids along the z dimension. This is an optional input, if it is not given we will try to precompute it.
header – A dictionary representing the header of the pfb file. This is an optional input, if it is not given we will read it from the pfb file directly.
read_sg_info – Whether or not to read subgrid information directly from the pfb file. Precalculating subgrid information does not always work correctly for some files, especially velocity files. This reads the subgrid offset bytes, subgrid indices and subgrid shapes, then computes the subgrid coordinates subgrid locations, and chunk sizes as normal
- __init__(file: str, precompute_subgrid_info: bool = True, p: int = None, q: int = None, r: int = None, header: Mapping[str, Number] = None, read_sg_info: bool = False)
- close()
- compute_subgrid_info()
Computes the subgrid information
- iloc_subgrid(idx: int) ndarray
Read a subgrid at some scalar index.
- Parameters:
idx – The index of the subgrid to read
- Returns:
The data from the idx’th subgrid.
- loc_subgrid(sg_p: int, sg_q: int, sg_r: int) ndarray
Read a subgrid given it’s (sg_p, sg_q, sg_r) coordinate in the subgrid-grid.
- Parameters:
sg_p – Index in the p subgrid to read.
sg_q – Index in the q subgrid to read.
sg_r – Index in the r subgrid to read.
- Returns:
The data from the (sg_p, sg_q, sg_r)’th subgrid.
- read_all_subgrids(mode: str = 'full', z_first: bool = True) Iterable[ndarray] | ndarray
Read all of the subgrids in the file.
- Parameters:
mode – Specifies how to arange the data from the subgrids before returning.
z_first – Whether the z dimension should be first. If true returned arrays have dimensions (‘z’, ‘y’, ‘x’) else (‘x’, ‘y’, ‘z’)
- Returns:
A numpy array or iterable of numpy arrays, depending on how
modeis set. Iffullthe returned array will be of dimensions (nx, ny, nz). Ifflatthe returned data will be a list of each of the subgrid arrays. Iftiledthe returned data will be a numpy array with dimensions (p, q, r) where each index of the array contains the subgrid data which also will be numpy array of floats with dimensions (sg_nx, sg_ny, sg_nz) where each of sg_nx, sg_ny, and sg_nz are the size of the subgrid array.
- read_header()
Reads the header
- read_subarray(start_x: int, start_y: int, start_z: int = 0, nx: int = 1, ny: int = 1, nz: int = None, z_first: bool = True) ndarray
Read a subsection of the full pfb file. For an example of what happens here consider the following image:
:: +——-+——-+ | | | | x|xx | +——-+——-+ | x|xx | | x|xx | +——-+——-+
Where each of the borders of the big grid are the four subgrids (2,2) that we are trying to index data from. The data to be selected falls in each of these subgrids, as denoted by the ‘x’ marks.
- Parameters:
start_x – The index to start at in the x dimension.
start_y – The index to start at in the y dimension.
start_z – The index to start at in the z dimension. This is optional, and if not provided is 0.
nx – The number of values to read in the x dimension. This is optional, and if not provided is 1.
ny – The number of values to read in the y dimension. This is optional, and if not provided is 1.
nz – The number of values to read in the z dimension. This is optional, and if not provided is None, which indicates to read all of the values.
z_first – Whether the z dimension should be first. If true returned arrays have dimensions (‘z’, ‘y’, ‘x’) else (‘x’, ‘y’, ‘z’)
- Returns:
A nd array with shape (nx, ny, nz).
- read_subgrid_header(skip_bytes: int = 64)
Reads a subgrid header at the position
skip_bytes
- read_subgrid_info()
Read the header for each subgrid directly from the pfb file, rather than calculating it via precalculate_subgrid_info
- parflow.tools.io.get_maingrid_and_remainder(nx, ny, nz, p, q, r)
Determines the sizes of the subgrids. Maingrid sizes are simprm_ny the integer value of the number of cells divided by the number of subgrids along each axis. The remainder is the modulus.
- Parameters:
nx – The length of the array along the x axis.
ny – The length of the array along the y axis.
nz – The length of the array along the z axis.
p – The number of subgrids along the x axis.
q – The number of subgrids along the y axis.
r – The number of subgrids along the z axis.
- parflow.tools.io.get_subgrid_loc(sel_subgrid, p, q, r)
Translate an integer subgrid to the location in 3d subgrid space.
- Parameters:
sel_subgrid – The scalar index of the subgrid of interest.
p – The number of subgrids along the x axis.
q – The number of subgrids along the y axis.
r – The number of subgrids along the z axis.
- parflow.tools.io.load_patch_matrix_from_asc_file(file_name)
- parflow.tools.io.load_patch_matrix_from_image_file(file_name, color_to_patch=None, fall_back_id=0)
- parflow.tools.io.load_patch_matrix_from_sa_file(file_name)
- parflow.tools.io.precalculate_subgrid_info(nx, ny, nz, p, q, r)
Computes all necessary subgrid information to index and read or write a pfb file.
- Parameters:
nx – Number of cells along the x-axis.
ny – Number of cells along the y-axis.
nz – Number of cells along the z-axis.
p – Number of subgrids along the x-axis.
q – Number of subgrids along the y-axis.
r – Number of subgrids along the z-axis.
- Returns:
- A tuple of arrays, (
subgrid_offsets, subgid_locations, subgrid_lower_left_indices, subgrid_shapes
)
- parflow.tools.io.read_clm(file_name, type='clmin')
- parflow.tools.io.read_pfb(file: str, keys: dict = None, mode: str = 'full', z_first: bool = True, read_sg_info: bool = True)
Read a single pfb file, and return the data therein
- Parameters:
file – The file to read.
keys –
A set of keys for indexing subarrays of the full pfb. Optional. This is mainly a trick for interfacing with xarray, but the format of the keys is:
:: {‘x’: {‘start’: start_x, ‘stop’: end_x},
’y’: {‘start’: start_y, ‘stop’: end_y}, ‘z’: {‘start’: start_z, ‘stop’: end_z}}
mode – The mode for the reader. See
ParflowBinaryReader::read_all_subgridsfor more information about what modes are available.read_sg_info – Precalculating subgrid information does not always work correctly for some files, especially velocity files. If
True, read subgrid info directly from the pfb file (slower, but more robust)
- Returns:
An nd array containing the data from the pfb file.
- parflow.tools.io.read_pfb_sequence(file_seq: Iterable[str], keys=None, z_first: bool = True, z_is: str = 'z', read_sg_info: bool = False)
An efficient wrapper to read a sequence of pfb files. This approach is faster than looping over the
read_pfbfunction because it caches the subgrid information from the first pfb file and then uses that to initialize all other readers.- Parameters:
file_seq – An iterable sequence of file names to be read.
keys –
A set of keys for indexing subarrays of the full pfb. Optional. This is mainly a trick for interfacing with xarray, but the format of the keys is:
:: {‘x’: {‘start’: start_x, ‘stop’: end_x},
’y’: {‘start’: start_y, ‘stop’: end_y}, ‘z’: {‘start’: start_z, ‘stop’: end_z}}
z_first – Whether the z dimension should be first. If true returned arrays have dimensions (‘z’, ‘y’, ‘x’) else (‘x’, ‘y’, ‘z’)
z_is – A descriptor of what the z axis represents. Can be one of ‘z’, ‘time’, ‘variable’. Default is ‘z’.
read_sg_info – Precalculating subgrid information does not always work correctly for some files, especially velocity files. If
True, read subgrid info directly from the pfb file (slower, but more robust)
- Returns:
An nd array containing the data from the files.
- parflow.tools.io.read_pfidb(file_path)
Load pfidb file into a Python dict
- parflow.tools.io.read_pfsb(file_path)
Read a ParFlow scattered binary file (pfsb) and return the data.
The data will be returned as a numpy array of shape (nz, ny, nx). To avoid confusion, there is no option to toggle ‘z_first’ on and off.
- parflow.tools.io.read_yaml(file_path)
Load yaml file into a Python dict
- parflow.tools.io.subgrid_lower_left(mg_nx, mg_ny, mg_nz, sg_p, sg_q, sg_r, rm_nx, rm_ny, rm_nz)
Get the index of the lower left corner of a subgrid.
- Parameters:
mg_nx – The standard length of a subgrid on the x-axis
mg_ny – The standard length of a subgrid on the y-axis
mg_nz – The standard length of a subgrid on the z-axis
sg_p – The index of the subgrid on the x-axis.
sg_q – The index of the subgrid on the y-axis.
sg_r – The index of the subgrid on the z-axis.
rm_nx – Remainder from the maingrid calculation on the x-axis
rm_ny – Remainder from the maingrid calculation on the y-axis
rm_nz – Remainder from the maingrid calculation on the z-axis
- parflow.tools.io.subgrid_size(mg_nx, mg_ny, mg_nz, sg_p, sg_q, sg_r, rm_nx, rm_ny, rm_nz)
Get the size of a subgrid
- Parameters:
mg_nx – The standard length of a subgrid on the x-axis
mg_ny – The standard length of a subgrid on the y-axis
mg_nz – The standard length of a subgrid on the z-axis
sg_p – The index of the subgrid on the x-axis.
sg_q – The index of the subgrid on the y-axis.
sg_r – The index of the subgrid on the z-axis.
rm_nx – Remainder from the maingrid calculation on the x-axis
rm_ny – Remainder from the maingrid calculation on the y-axis
rm_nz – Remainder from the maingrid calculation on the z-axis
- parflow.tools.io.to_native_type(string)
Converting a string to a value in native format. Used for converting .pfidb files
- parflow.tools.io.undist(undis_name: str)
Undistribute PFB files. Distributed PFB files can be in two formats. The split file model creates a file per rank; each rank file has the rank index appended to the fileneme. The sequential model writes all data to a single file and creates and index file (.dist extension) to aid in locating offsets.
The Python interface currently can’t create the split file model but this should undistribute the split files, which is just a cat operation.
- Parameters:
undis_name – This can be the full undis_name used, in this case all files
will be undistributed. Also a specific PFB file can be specified.
- parflow.tools.io.write_dict(dict_obj, file_name)
Write a Python dict into a file_name using the extension to determine its format.
- parflow.tools.io.write_dict_as_json(dict_obj, file_name)
Write a Python dict in a json format inside the provided file_name
- parflow.tools.io.write_dict_as_pfidb(dict_obj, file_name)
Write a Python dict in a pfidb format inside the provided file_name
- parflow.tools.io.write_dict_as_yaml(dict_obj, file_name)
Write a Python dict in a pfidb format inside the provided file_name
- parflow.tools.io.write_dist(file, sg_offs)
Write a distfile.
- Parameters:
file – The path of the file to be written.
sg_offs – The subgrid offsets.
- parflow.tools.io.write_patch_matrix_as_asc(matrix, file_name, xllcorner=0.0, yllcorner=0.0, cellsize=1.0, NODATA_value=0, **kwargs)
Write asc for pfsol
- parflow.tools.io.write_patch_matrix_as_sa(matrix, file_name, **kwargs)
Write asc for pfsol
- parflow.tools.io.write_pfb(file, array, p=1, q=1, r=1, x=0.0, y=0.0, z=0.0, dx=1.0, dy=1.0, dz=1.0, z_first=True, dist=True, **kwargs)
Write a single pfb file. The data must be a 3D numpy array with float64 values. The number of subgrids in the saved file will be p * q * r. This is regardless of the number of subgrids in the PFB file loaded by the ParflowBinaryReader into the numpy array. Therefore, loading a file with ParflowBinaryReader and saving it with this method may restructure the file into a different number of subgrids if you change these values.
If dist is True then also write a file with the .dist extension added to the file_name. The .dist file will contain one line per subgrid with the offset of the subgrid in the .pfb file.
- Parameters:
file – The name of the file to write the array to.
array – The array to write.
p – Number of subgrids in the x direction.
q – Number of subgrids in the y direction.
r – Number of subgrids in the z direction.
x – The length of the x-axis
y – The length of the y-axis
z – The length of the z-axis
dx – The spacing between cells in the x direction
dy – The spacing between cells in the y direction
dz – The spacing between cells in the z direction
z_first – Whether the z-axis should be first or last.
dist – Whether to write the distfile in addition to the pfb.
kwargs – Extra keyword arguments, primarily to eat unnecessary args by passing in a dictionary with **dict.