Skip to article frontmatterSkip to article content

Reading parameters

Data products exported from Open Polar Radar contain a huge amount of metadata, stored primarily in param_<processing step> structures. These are initially encoded in spreadsheets, which may be found in the opr_params git repository and follow the schema described in the Parameter Spreadsheet Guide and the Parameter Spreadsheets section of the OPR Toolbox Guide.

When data is processed, the parameters used for each processing stage are saved with the exported data file. xOPR will load as much of this data as possible and make it available as attributes of the returned datasets.

Generally, all files you load should have a param_records attribute that encodes the parameter spreadsheet at the point where the raw data was broken into frames. Depending on the processing level you load, you will also find parameter dictionaries for later processing steps. For example, CSARP_standard data products should have a param_sar dictionary and CSARP_qlook products should have a param_qlook dictionary.

(For a reference to the processing stages, see Processing Steps on the OPR wiki.)

%load_ext autoreload
%autoreload 2

import xarray as xr

import xopr
# Establish an OPR session
# You'll probably want to set a cache directory if you're running this locally to speed
# up subsequent requests. You can do other things like customize the STAC API endpoint,
# but you shouldn't need to do that for most use cases.
opr = xopr.OPRConnection(cache_dir="radar_cache")

# Or you can open a connection without a cache directory (for example, if you're parallelizing
# this on a cloud cluster without persistent storage).
#opr = xopr.OPRConnection()
season, flight_id = '2022_Antarctica_BaslerMKB', '20230109_01'
#season, flight_id = '2016_Antarctica_DC8', '20161117_06'
print(f"Selected flight: {flight_id} from season {season}")

stac_items = opr.query_frames(seasons=[season], flight_ids=[flight_id], max_items=2)
frames = opr.load_frames(stac_items, data_product='CSARP_standard')
example_frame = frames[0]
Selected flight: 20230109_01 from season 2022_Antarctica_BaslerMKB
example_frame.xopr
Loading...

The structure of each parameter dictionary should be the same (see Parameter Spreadsheet in the OPR Toolbox Guide). The multiple parameter dictionaries encode the history of the parameters throughout the processing. Generally, if you’re looking for a parameter that is fundamental to the radar instrument, it shouldn’t matter which structure you read since this won’t change. For example, here we’re reading the start frequency of the chirp from param_records and param_sar and getting the same value.

print(example_frame.attrs['param_records']['radar']['wfs']['f0'])
print(example_frame.attrs['param_sar']['radar']['wfs']['f0'])
52500000.0
52500000.0

If you’re looking for a parameter specific to the post-processing, it’s generally best to use the parameter structure associated with the level of processing you’re working with.

print(example_frame.attrs['param_sar']['sar']['chunk_len'])
5000.0

There are some parts of the parameter structure that we can’t really load correctly. Matlab function handles will show up like this, but there’s not much you can actually do with this:

example_frame.attrs['param_records']['radar']['lever_arm_fh']
{'function_handle': {'file': '/tmp/dangermo/r1n02/.mcrCache9.14/cluste1/kucresis/scratch/dangermo/scripts/opr/matlab/processing/lever_arm.m', 'function': 'lever_arm', 'type': 'simple'}, 'matlabroot': '/cresis/snfs1/projects/software/matlab/MCR_install/R2023a', 'sentinel': '@', 'separator': '/'}

When you combine multiple frames together, you can use xOPR’s xopr.util.merge_dicts_no_conflicts to combine attributes. This helper function will navigate through the nested dictionaries and keep only the parameters that are common across all input frames.

from xopr.util import merge_dicts_no_conflicts
xr.concat(frames, dim='slow_time', combine_attrs=merge_dicts_no_conflicts).sortby('slow_time').xopr
Loading...

Of course, if you don’t want to remember all that, you can just directly call the xOPR helper function for merging flights:

opr.merge_flights_from_frames(frames)[0].xopr
Loading...