Profile
Docstrings for the Profile class
6 minute read
Objects
Profile()
Profile.read_en4()
Profile.read_wod()
Profile.subset_indices_lonlat_box()
Profile.plot_profile()
Profile.plot_map()
Profile.plot_ts_diagram()
Profile.process_en4()
Profile.calculate_all_en4_qc_flags()
Profile.obs_operator()
Profile.reshape_2d()
Profile.time_slice()
Profile Class
Profile()
class Profile(Indexed):
INDEXED type class for storing data from a CTD Profile (or similar
down and up observations). The structure of the class is based around having
discrete profile locations with independent depth dimensions and coords.
The class dataset should contain two dimensions:
> id_dim :: The profiles dimension. Each element of this dimension
contains data (e.g. cast) for an individual location.
> z_dim :: The dimension for depth levels. A profile object does not
need to have shared depths, so NaNs might be used to
pad any depth array.
Alongside these dimensions, the following minimal coordinates should also
be available:
> longitude (id_dim) :: 1D array of longitudes, one for each id_dim
> latitude (id_dim) :: 1D array of latitudes, one for each id_dim
> time (id_dim) :: 1D array of times, one for each id_dim
> depth (id_dim, z_dim) :: 2D array of depths, with different depth
levels being provided for each profile.
Note that these depth levels need to be
stored in a 2D array, so NaNs can be used
to pad out profiles with shallower depths.
> id_name (id_dim) :: [Optional] Name of id_dim/case or id_dim number.
You may create an empty profile object by using profile = coast.Profile().
You may then add your own dataset to the object profile or use one of the
functions within Profile() for reading common profile datasets:
> read_en4()
> read_wod()
Optionally, you may pass a dataset to the Profile object on creation:
profile = coast.Profile(dataset = profile_dataset)
A config file can also be provided, in which case any netcdf read functions
will rename dimensions and variables as dictated.
Profile.read_en4()
def Profile.read_en4(self, fn_en4, chunks=unknown, multiple=False):
Reads a single or multiple EN4 netCDF files into the COAsT profile
data structure.
Parameters
----------
fn_en4 : TYPE
path to data file.
chunks : dict, optional
Chunking specification
multiple : TYPE, optional
True if reading multiple files otherwise False
Returns
-------
None. Populates dataset within Profile object.
Profile.read_wod()
def Profile.read_wod(self, fn_wod, chunks=unknown):
Reads a single World Ocean Database netCDF files into the COAsT profile data structure.
Args:
fn_wod (str): path to data file
chunks (dict): chunks
Profile.subset_indices_lonlat_box()
def Profile.subset_indices_lonlat_box(self, lonbounds, latbounds):
Get a subset of this Profile() object in a spatial box.
lonbounds -- Array of form [min_longitude=-180, max_longitude=180]
latbounds -- Array of form [min_latitude, max_latitude]
return: A new profile object containing subsetted data
Profile.plot_profile()
def Profile.plot_profile(self, var, profile_indices=None):
None
Profile.plot_map()
def Profile.plot_map(self, var_str=None):
None
Profile.plot_ts_diagram()
def Profile.plot_ts_diagram(self, profile_index, var_t=potential_temperature, var_s=practical_salinity):
None
Profile.process_en4()
def Profile.process_en4(self, sort_time=True):
VERSION 1.4 (05/07/2021)
PREPROCESSES EN4 data ready for comparison with model data.
This routine will cut out a desired geographical box of EN4 data and
then apply quality control according to the available flags in the
netCDF files. Quality control happens in two steps:
1. Where a whole data profile is flagged, it is completely removed
from the dataset
2. Where a single datapoint is rejected in either temperature or
salinity, it is set to NaN.
This routine attempts to use xarray/dask chunking magic to keep
memory useage low however some memory is still needed for loading
flags etc. May be slow if using large EN4 datasets.
Routine will return a processed profile object dataset and can write
the new dataset to file if fn_out is defined. If saving to the
PROFILE object, be aware that DASK computations will not have happened
and will need to be done using .load(), .compute() or similar before
accessing the values. IF using multiple EN4 files or large dataset,
make sure you have chunked the data over N_PROF dimension.
INPUTS
fn_out (str) : Full path to a desired output file. If unspecified
then nothing is written.
EXAMPLE USEAGE:
profile = coast.PROFILE()
profile.read_EN4(fn_en4, chunks={'N_PROF':10000})
fn_out = '~/output_file.nc'
new_profile = profile.preprocess_en4(fn_out = fn_out,
lonbounds = [-10, 10],
latbounds = [45, 65])
Profile.calculate_all_en4_qc_flags()
@classmethod
def Profile.calculate_all_en4_qc_flags(cls):
Brute force method for identifying all rejected points according to
EN4 binary integers. It can be slow to convert large numbers of integers
to a sequence of bits and is actually quicker to just generate every
combination of possible QC integers. That's what this routine does.
Used in PROFILE.preprocess_en4().
INPUTS
NO INPUTS
OUTPUTS
qc_integers_tem : Array of integers signifying the rejection of ONLY
temperature datapoints
qc_integers_sal : Array of integers signifying the rejection of ONLY
salinity datapoints
qc_integers_both : Array of integers signifying the rejection of BOTH
temperature and salinity datapoints.
Profile.obs_operator()
def Profile.obs_operator(self, gridded, mask_bottom_level=True):
VERSION 2.0 (04/10/2021)
Author: David Byrne
Does a spatial and time interpolation of a gridded object's data.
A nearest neighbour approach is used for both interpolations. Both
datasets (the Profile and Gridded objects) must contain longitude,
latitude and time coordinates. This routine expects there to be a
landmask variable in the gridded object. This is is not available,
then place an array of zeros into the dataset, with dimensions
(y_dim, x_dim).
This routine will do the interpolation based on the chunking applied
to the Gridded object. Please ensure you have the available memory to
have an entire Gridded chunk loaded to memory. If multiple files are
used, then using one chunk per file will be most efficient. Time
chunking is generally the better option for this routine.
INPUTS:
gridded (Gridded) : gridded object created on t-grid
mask_bottom_level (bool) : Whether or not to mask any data below the
model's bottom level. If True, then ensure
the Gridded object's dataset contain's a
bottom_level variable with dims
(y_dim, x_dim).
OUTPUTS:
Returns a new PROFILE object containing a computed dataset of extracted
profiles.
Profile.reshape_2d()
def Profile.reshape_2d(self, var_user_want):
OBSERVATION type class for reshaping World Ocean Data (WOD) or similar that
contains 1D profiles (profile * depth levels) into a 2D array.
Note that its variable has its own dimention and in some profiles
only some variables are present. WOD can be observed depth or a
standard depth as regrided by NOAA.
Args:
> X -- The variable (e.g,Temperatute, Salinity, Oxygen, DIC ..)
> X_N -- Dimensions of observed variable as 1D
(essentially number of obs variable = casts * osberved depths)
> casts -- Dimension for locations of observations (ie. profiles)
> z_N -- Dimension for depth levels of all observations as 1D
(essentially number of depths = casts * osberved depths)
> X_row_size -- Gives the vertical index (number of depths)
for each variable
Profile.time_slice()
def Profile.time_slice(self, date0, date1):
Return new Gridded object, indexed between dates date0 and date1
Feedback
Was this page helpful?
Glad to hear it!
Sorry to hear that. Please tell us how we can improve.
Last modified November 23, 2022: Updated docstrings from coast repo. (9daee18)