text: #!/usr/bin/env python
  u"""
  HDF5_cryosat_L2.py (08/2020)
  Reads and Writes HDF5 files for CryoSat-2 Level-2 data products
  Supported CryoSat Modes: LRM, SAR, SARin, FDM, SID, GDR
  
  OUTPUTS a formatted HDF5 file with:
      Data_1Hz: Time and Orbit Parameters
      Corrections: Elevation Corrections and Flags
      Data_20Hz: Geolocation and Elevation Measurements with Quality Parameters
      METADATA: MPH, SPH and DSD Header data
  
  OPTIONS:
      BASELINE (HDF5_cryosat_L2): CryoSat-2 baseline (A, B, C)
      FILENAME (HDF5_cryosat_L2): output HDF5 file name
      TITLE (HDF5_cryosat_L2): output file description
      HEADER (HDF5_cryosat_L2): output CryoSat-2 file headers (MPH, SPH, DSD)
          1: for single CryoSat-2 files
          2: for merged CryoSat-2 files from convert_cryosat_L2.py
      CLOBBER (HDF5_cryosat_L2): overwrite existing HDF5 file
      VERBOSE: print HDF5 structure parameters to screen
      ATTRIBUTES (read_HDF5_cryosat_L2): input variable attributes from HDF5 file
  
  PYTHON DEPENDENCIES:
      numpy: Scientific Computing Tools For Python (https://numpy.org)
      h5py: Python interface for Hierarchal Data Format 5 (HDF5)
          (https://www.h5py.org/)
  
  UPDATE HISTORY:
      Updated 08/2020: flake8 updates for python3
      Updated 02/2020: convert from hard to soft tabulation
      Updated 11/2019: add netCDF4 Time (TAI seconds since 2000-01-01)
      Updated 10/2019: changing Y/N flags to True/False
      Updated 09/2019: updates for Baseline D
      Updated 04/2019: print HDF5 keys from list for python3 compatibility
      Updated 06/2018: use items instead of iteritems for python3 compatibility
      Updated 11/2016: added Abs_Orbit and Ascending_flag to Data_1Hz outputs
      Updated 05/2016: using __future__ print function
      Written 03/2016
  """
  from __future__ import print_function
  
  import os
  import re
  import h5py
  
  #-- PURPOSE: write CryoSat-2 HDF5 files
  def HDF5_cryosat_L2(CS_l2_mds, BASELINE, FILENAME='', TITLE='', HEADER=0,
      CLOBBER=True, VERBOSE=False):
      #-- setting HDF5 clobber attribute
      if CLOBBER:
          clobber = 'w'
      else:
          clobber = 'w-'
  
      #-- getting HDF5 dataset attributes for each variable
      CS_l2_attrib = cryosat_L2_attributes(BASELINE)
  
      #-- open output HDF5 file
      fileID = h5py.File(os.path.expanduser(FILENAME), clobber)
      #-- create sub-groups within HDF5 file
      fileID.create_group('Data_1Hz')
      fileID.create_group('Data_20Hz')
      fileID.create_group('Corrections')
  
      #-- Dimensions of parameters
      n_records,n_blocks = CS_l2_mds['Data_20Hz']['D_time_mics'].shape
  
      #-- find keys to output (do not output empty Spares variables)
      Data_1Hz_keys = [key for key in CS_l2_mds['Data_1Hz'].keys() if not
          re.search('Spare',key)]
      Data_20Hz_keys = [key for key in CS_l2_mds['Data_20Hz'].keys() if not
          re.search('Spare',key)]
      correction_keys = [key for key in CS_l2_mds['Corrections'].keys() if not
          re.search('Spare',key)]
  
      #-- create HDF5 records
      h5 = {}
      h5['Data_1Hz'] = {}
      h5['Data_20Hz'] = {}
      h5['Corrections'] = {}
      #-- CryoSat-2 1 Hz data fields (Location Group)
      #-- Time and Orbit Parameters plus Measurement Mode
      for key in Data_1Hz_keys:
          val = CS_l2_mds['Data_1Hz'][key]
          #-- Defining the HDF5 dataset variables
          h5['Data_1Hz'][key] = fileID.create_dataset('Data_1Hz/{0}'.format(key),
              (n_records,), data=val, dtype=val.dtype, compression='gzip')
          #-- add HDF5 variable attributes
          for att_name,att_val in CS_l2_attrib['Data_1Hz'][key].items():
              h5['Data_1Hz'][key].attrs[att_name] = att_val
          #-- attach dimensions
          h5['Data_1Hz'][key].dims[0].label='CS_L2_MDS_REC_SIZE'
      #-- CryoSat-2 20 Hz data fields (Measurement Group)
      #-- Derived from instrument measurement parameters
      for key in Data_20Hz_keys:
          val = CS_l2_mds['Data_20Hz'][key]
          #-- Defining the HDF5 dataset variables
          h5['Data_20Hz'][key] = fileID.create_dataset('Data_20Hz/{0}'.format(key),
              (n_records,n_blocks,), data=val, dtype=val.dtype, compression='gzip')
          #-- add HDF5 variable attributes
          for att_name,att_val in CS_l2_attrib['Data_20Hz'][key].items():
              h5['Data_20Hz'][key].attrs[att_name] = att_val
          #-- attach dimensions
          h5['Data_20Hz'][key].dims[0].label='CS_L2_MDS_REC_SIZE'
          h5['Data_20Hz'][key].dims[1].label='CS_L2_MDS_BLOCK_SIZE'
      #-- CryoSat-2 geophysical corrections (External Corrections Group)
      for key in correction_keys:
          val = CS_l2_mds['Corrections'][key]
          #-- Defining the HDF5 dataset variables
          h5['Corrections'][key] = fileID.create_dataset('Corrections/{0}'.format(key),
              (n_records,), data=val, dtype=val.dtype, compression='gzip')
          #-- add HDF5 variable attributes
          for att_name,att_val in CS_l2_attrib['Corrections'][key].items():
              h5['Corrections'][key].attrs[att_name] = att_val
          #-- attach dimensions
          h5['Corrections'][key].dims[0].label='CS_L2_MDS_REC_SIZE'
  
      #-- output MPH/SPH/DSD headers as group attributes
      if (HEADER == 1):
          #-- HEADER 1 is for single CryoSat-2 files
          fileID.create_group('METADATA')
          fileID['METADATA'].create_group('MPH')
          fileID['METADATA'].create_group('SPH')
          fileID['METADATA'].create_group('DSD')
          #-- Main Product Header (MPH) are all strings
          for att_name,att_val in CS_l2_mds['METADATA']['MPH'].items():
              fileID['METADATA']['MPH'].attrs[att_name] = att_val
          #-- Specific Product Header (SPH) are both strings and dictionaries
          for att_name,att_val in CS_l2_mds['METADATA']['SPH'].items():
              if isinstance(att_val,dict):
                  #-- if att_val is dictionary
                  fileID['METADATA']['SPH'].create_group(att_name)
                  for ds_name,ds_val in att_val.items():
                      fileID['METADATA']['SPH'][att_name].attrs[ds_name] = ds_val
              elif isinstance(att_val,str) and att_name:
                  #-- if att_val is string
                  fileID['METADATA']['SPH'].attrs[att_name] = att_val
          #-- Data Set Descriptors (DSD) are all strings
          for att_name,att_val in CS_l2_mds['METADATA']['DSD'].items():
              fileID['METADATA']['DSD'].attrs[att_name] = att_val
      elif (HEADER == 2):
          #-- HEADER 2 is for merged CryoSat-2 files from convert_cryosat_L2.py
          fileID.create_group('METADATA')
          fileID['METADATA'].create_group('MPH')
          fileID['METADATA'].create_group('SPH')
          fileID['METADATA'].create_group('DSD')
          #-- Main Product Header (MPH) are all strings
          for fi in CS_l2_mds['METADATA']['MPH'].keys():
              fileID['METADATA']['MPH'].create_group(fi)
              for att_name,att_val in CS_l2_mds['METADATA']['MPH'][fi].items():
                  fileID['METADATA']['MPH'][fi].attrs[att_name] = att_val
          #-- Specific Product Header (SPH) are both strings and dictionaries
          for fi in CS_l2_mds['METADATA']['SPH'].keys():
              fileID['METADATA']['SPH'].create_group(fi)
              for att_name,att_val in CS_l2_mds['METADATA']['SPH'][fi].items():
                  if isinstance(att_val,dict):
                      #-- if att_val is dictionary
                      fileID['METADATA']['SPH'][fi].create_group(att_name)
                      for dsn,dsv in att_val.items():
                          fileID['METADATA']['SPH'][fi][att_name].attrs[dsn] = dsv
                  elif isinstance(att_val,str) and att_name:
                      #-- if att_val is string
                      fileID['METADATA']['SPH'][fi].attrs[att_name] = att_val
          #-- Data Set Descriptors (DSD) are all strings
          for fi in CS_l2_mds['METADATA']['DSD'].keys():
              fileID['METADATA']['DSD'].create_group(fi)
              for att_name,att_val in CS_l2_mds['METADATA']['DSD'][fi].items():
                  fileID['METADATA']['DSD'][fi].attrs[att_name] = att_val
  
      #-- output file title
      fileID.attrs['description'] = TITLE
  
      #-- Output HDF5 structure information
      if VERBOSE:
          print(FILENAME)
          print(list(fileID.keys()))
  
      #-- Closing the HDF5 file
      fileID.close()
  
  #-- PURPOSE: read CryoSat-2 HDF5 files
  def read_HDF5_cryosat_L2(FILENAME, ATTRIBUTES=True, VERBOSE=False):
      #-- Open the HDF5 file for reading
      fileID = h5py.File(os.path.expanduser(FILENAME), 'r')
  
      #-- Output HDF5 file information
      if VERBOSE:
          print(fileID.filename)
          print(list(fileID.keys()))
  
      #-- allocate python dictionaries for output CS_l2_mds variables
      CS_l2_mds = {}
      CS_l2_mds['Data_1Hz'] = {}
      CS_l2_mds['Data_20Hz'] = {}
      CS_l2_mds['Corrections'] = {}
      #-- get each HDF5 variable
      #-- CryoSat-2 Location Group
      for key in fileID['Data_1Hz'].keys():
          CS_l2_mds['Data_1Hz'][key] = fileID['Data_1Hz'][key][:]
      #-- CryoSat-2 Measurement Group
      for key in fileID['Data_20Hz'].keys():
          CS_l2_mds['Data_20Hz'][key] = fileID['Data_20Hz'][key][:,:]
      #-- CryoSat-2 External Corrections Group
      for key in fileID['Corrections'].keys():
          CS_l2_mds['Corrections'][key] = fileID['Corrections'][key][:]
  
      #-- Getting attributes of included variables
      if ATTRIBUTES:
          #-- allocate python dictionaries for output CS_l2_mds attributes
          CS_l2_mds['Attributes'] = {}
          CS_l2_mds['Attributes']['Data_1Hz'] = {}
          CS_l2_mds['Attributes']['Data_20Hz'] = {}
          CS_l2_mds['Attributes']['Corrections'] = {}
          #-- CryoSat-2 Location Group
          for key in fileID['Data_1Hz'].keys():
              CS_l2_mds['Attributes']['Data_1Hz'][key] = {}
              for att_name,att_val in fileID['Data_1Hz'][key].attrs.items():
                  CS_l2_mds['Attributes']['Data_1Hz'][key][att_name] = att_val
          #-- CryoSat-2 Measurement Group
          for key in fileID['Data_20Hz'].keys():
              CS_l2_mds['Attributes']['Data_20Hz'][key] = {}
              for att_name,att_val in fileID['Data_20Hz'][key].attrs.items():
                  CS_l2_mds['Attributes']['Data_20Hz'][key][att_name] = att_val
          #-- CryoSat-2 External Corrections Group
          for key in fileID['Corrections'].keys():
              CS_l2_mds['Attributes']['Corrections'][key] = {}
              for att_name,att_val in fileID['Corrections'][key].attrs.items():
                  CS_l2_mds['Attributes']['Corrections'][key][att_name] = att_val
          #-- Global attribute description
          CS_l2_mds['Attributes']['title'] = fileID.attrs['description']
  
      #-- Closing the HDF5 file
      fileID.close()
      return CS_l2_mds
  
  #-- PURPOSE: get the number of records and number of blocks in an HDF5 file
  def HDF5_cryosat_L2_shape(FILENAME):
      #-- Open the HDF5 file for reading
      fileID = h5py.File(os.path.expanduser(FILENAME), 'r')
      n_records,n_blocks = fileID['Data_20Hz']['D_time_mics'].shape
      #-- Closing the HDF5 file
      fileID.close()
      return (n_records,n_blocks)
  
  #-- PURPOSE: get attribute names for baseline
  def cryosat_L2_attributes(BASELINE):
      #-- CryoSat-2 1 Hz data fields (Location Group)
      #-- Time and Orbit Parameters plus Measurement Mode
      L2_1Hz_attributes = {}
      #-- Time: netCDF4 TAI time since 2000-01-01 00:00:00
      L2_1Hz_attributes['Time'] = {}
      L2_1Hz_attributes['Time']['long_name'] = 'MDSR time stamp'
      L2_1Hz_attributes['Time']['units'] = 'seconds since 2000-01-01 00:00:00.0'
      L2_1Hz_attributes['Time']['description'] = ('TAI time counted in seconds '
          'since 2000-01-01 00:00:00')
      L2_1Hz_attributes['Time']['hertz'] = 1
      L2_1Hz_attributes['Time']['calendar'] = 'gregorian'
      L2_1Hz_attributes['Time']['standard_name'] = 'time'
      #-- Time: day part
      L2_1Hz_attributes['Day'] = {}
      L2_1Hz_attributes['Day']['long_name'] = 'MDSR time stamp days'
      L2_1Hz_attributes['Day']['units'] = 'days since 2000-01-01 00:00:00 TAI'
      L2_1Hz_attributes['Day']['hertz'] = 1
      #-- Time: second part
      L2_1Hz_attributes['Second'] = {}
      L2_1Hz_attributes['Second']['long_name'] = 'MDSR time stamp seconds'
      L2_1Hz_attributes['Second']['units'] = 'seconds'
      L2_1Hz_attributes['Second']['hertz'] = 1
      #-- Time: microsecond part
      L2_1Hz_attributes['Micsec'] = {}
      L2_1Hz_attributes['Micsec']['long_name'] = 'MDSR time stamp microseconds'
      L2_1Hz_attributes['Micsec']['units'] = 'microseconds'
      L2_1Hz_attributes['Micsec']['hertz'] = 1
      #-- SIRAL mode
      L2_1Hz_attributes['Siral_mode'] = {}
      L2_1Hz_attributes['Siral_mode']['long_name'] = 'SIRAL mode'
      L2_1Hz_attributes['Siral_mode']['hertz'] = 1
      #-- Lat_1Hz: packed units (0.1 micro-degree, 1e-7 degrees)
      L2_1Hz_attributes['Lat_1Hz'] = {}
      L2_1Hz_attributes['Lat_1Hz']['long_name'] = 'Latitude of measurement'
      L2_1Hz_attributes['Lat_1Hz']['description'] = ('Corresponding to the nadir '
          'position at the time of the 1Hz time stamp')
      L2_1Hz_attributes['Lat_1Hz']['units'] = '0.1 micro-degree'
      L2_1Hz_attributes['Lat_1Hz']['valid_min'] = -9e8
      L2_1Hz_attributes['Lat_1Hz']['valid_max'] = 9e8
      L2_1Hz_attributes['Lat_1Hz']['hertz'] = 1
      #-- Lon_1Hz: packed units (0.1 micro-degree, 1e-7 degrees)
      L2_1Hz_attributes['Lon_1Hz'] = {}
      L2_1Hz_attributes['Lon_1Hz']['long_name'] = 'Longitude of measurement'
      L2_1Hz_attributes['Lon_1Hz']['description'] = ('Corresponding to the nadir '
          'position at the time of the 1Hz time stamp')
      L2_1Hz_attributes['Lon_1Hz']['units'] = '0.1 micro-degree'
      L2_1Hz_attributes['Lon_1Hz']['valid_min'] = -18e8
      L2_1Hz_attributes['Lon_1Hz']['valid_max'] = 18e8
      L2_1Hz_attributes['Lon_1Hz']['hertz'] = 1
      #-- Alt_1Hz: packed units (mm, 1e-3 m)
      #-- Altitude of COG above reference ellipsoid (interpolated value)
      L2_1Hz_attributes['Alt_1Hz'] = {}
      L2_1Hz_attributes['Alt_1Hz']['long_name'] = 'Altitude'
      L2_1Hz_attributes['Alt_1Hz']['description'] = ('Altitude of Satellite COG '
          'above reference ellipsoid at nadir (interpolated value)')
      L2_1Hz_attributes['Alt_1Hz']['units'] = 'millimeters'
      L2_1Hz_attributes['Alt_1Hz']['hertz'] = 1
  
      #-- Spacecraft mispointing (Roll, Pitch, and Yaw for Baseline-C and D)
      if BASELINE in ('C','D'):
          #-- Roll: packed units (0.1 micro-degree, 1e-7 degrees)
          L2_1Hz_attributes['Roll'] = {}
          L2_1Hz_attributes['Roll']['long_name'] = ('Spacecraft roll angle '
              'derived from star trackers')
          L2_1Hz_attributes['Roll']['units'] = '0.1 micro-degree'
          L2_1Hz_attributes['Roll']['hertz'] = 1
          #-- Pitch: packed units (0.1 micro-degree, 1e-7 degrees)
          L2_1Hz_attributes['Pitch'] = {}
          L2_1Hz_attributes['Pitch']['long_name'] = ('Spacecraft pitch angle '
              'derived from star trackers')
          L2_1Hz_attributes['Pitch']['units'] = '0.1 micro-degree'
          L2_1Hz_attributes['Pitch']['hertz'] = 1
          #-- Yaw: packed units (0.1 micro-degree, 1e-7 degrees)
          L2_1Hz_attributes['Yaw'] = {}
          L2_1Hz_attributes['Yaw']['long_name'] = ('Spacecraft yaw angle '
              'derived from star trackers')
          L2_1Hz_attributes['Yaw']['units'] = '0.1 micro-degree'
          L2_1Hz_attributes['Yaw']['hertz'] = 1
      else:
          #-- Mispointing: packed units (millidegrees, 1e-3 degrees)
          L2_1Hz_attributes['Mispointing'] = {}
          L2_1Hz_attributes['Mispointing']['long_name'] =('Spacecraft mispointing'
              'derived from star trackers')
          L2_1Hz_attributes['Mispointing']['units'] = 'millidegrees'
          L2_1Hz_attributes['Mispointing']['hertz'] = 1
  
      #-- Number of valid records in the block of twenty that contain data
      #-- Last few records of the last block of a datset may be blank blocks
      #-- inserted to bring the file up to a multiple of twenty.
      L2_1Hz_attributes['N_valid'] = {}
      L2_1Hz_attributes['N_valid']['long_name'] = 'Number of valid measurements'
      L2_1Hz_attributes['N_valid']['description'] = ('The number of records in '
          'the block of twenty that actually contain data. The last few records '
          'of the last block of a datset may be blank blocks inserted to bring '
          'the file up to a multiple of twenty.')
      L2_1Hz_attributes['N_valid']['hertz'] = 1
  
      #-- Absolute Orbit Number from MPH Header
      L2_1Hz_attributes['Abs_Orbit'] = {}
      L2_1Hz_attributes['Abs_Orbit']['long_name'] = 'Absolute Orbit Number'
      L2_1Hz_attributes['Abs_Orbit']['units'] = 'Count'
      L2_1Hz_attributes['Abs_Orbit']['hertz'] = 1
      #-- Ascending Flag from SPH Header
      L2_1Hz_attributes['Ascending_flag'] = {}
      L2_1Hz_attributes['Ascending_flag']['long_name'] = 'Ascending Flag'
      L2_1Hz_attributes['Ascending_flag']['description'] = ('If True: satellite '
          'is in ascending orbit. If False: satellite is in descending orbit.')
      L2_1Hz_attributes['Ascending_flag']['hertz'] = 1
  
      #-- CryoSat-2 geophysical corrections (External Corrections Group)
      L2_corr_attributes = {}
      #-- Dry Tropospheric Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['dryTrop'] = {}
      L2_corr_attributes['dryTrop']['long_name'] = 'Dry Tropospheric Correction'
      L2_corr_attributes['dryTrop']['description'] = ('Altimeter range correction'
          ' due to the dry-gas component of the troposphere')
      L2_corr_attributes['dryTrop']['units'] = 'millimeters'
      L2_corr_attributes['dryTrop']['hertz'] = 1
      #-- Wet Tropospheric Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['wetTrop'] = {}
      L2_corr_attributes['wetTrop']['long_name'] = 'Wet Tropospheric Correction'
      L2_corr_attributes['wetTrop']['description'] = ('Altimeter range correction'
          ' due to the water component of the troposphere')
      L2_corr_attributes['wetTrop']['units'] = 'millimeters'
      L2_corr_attributes['wetTrop']['hertz'] = 1
      #-- Inverse Barometric Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['InvBar'] = {}
      L2_corr_attributes['InvBar']['long_name'] = 'Inverse Barometric Correction'
      L2_corr_attributes['InvBar']['description'] = ('Altimeter range correction '
          'for the depression of the ocean surface caused by the local barometric '
          'pressure')
      L2_corr_attributes['InvBar']['units'] = 'millimeters'
      L2_corr_attributes['InvBar']['hertz'] = 1
      #-- Dynamic Atmosphere Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['DAC'] = {}
      L2_corr_attributes['DAC']['long_name'] = 'Dynamic Atmosphere Correction'
      L2_corr_attributes['DAC']['description'] = ('Altimeter range correction '
          'for the dynamic component of the wind effect on the ocean '
          '(applicable only on ocean surface without sea-ice)')
      L2_corr_attributes['DAC']['units'] = 'millimeters'
      L2_corr_attributes['DAC']['hertz'] = 1
      #-- Ionospheric Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['Iono'] = {}
      L2_corr_attributes['Iono']['long_name'] = 'Ionospheric Correction'
      L2_corr_attributes['Iono']['description'] = ('Altimeter range correction '
          'for the delay of the radar pulse caused by free electrons in the '
          'ionosphere. Computed from a simple model in NRT data.')
      L2_corr_attributes['Iono']['units'] = 'millimeters'
      L2_corr_attributes['Iono']['hertz'] = 1
      #-- GIM Ionospheric Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['Iono_GIM'] = {}
      L2_corr_attributes['Iono_GIM']['long_name'] = 'GIM Ionospheric Correction'
      L2_corr_attributes['Iono_GIM']['description'] = ('Altimeter range correction '
          'for the delay of the radar pulse caused by free electrons in the '
          'ionosphere. Computed from GPS satellite derived (GIM) map. '
          'This correction is an alternative and only one should be used')
      L2_corr_attributes['Iono_GIM']['units'] = 'millimeters'
      L2_corr_attributes['Iono_GIM']['hertz'] = 1
      #-- Sea State Bias Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['SSB'] = {}
      L2_corr_attributes['SSB']['long_name'] = 'Sea State Bias Correction'
      L2_corr_attributes['SSB']['description'] = ('Empirical altimeter range '
          'correction proportional to the significant wave height which '
          'compensates for the asymmetric shape of ocean waves. '
          '(computed by the geophysical CFI library)')
      L2_corr_attributes['SSB']['units'] = 'millimeters'
      L2_corr_attributes['SSB']['hertz'] = 1
      #-- Ocean tide Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['ocTideElv'] = {}
      L2_corr_attributes['ocTideElv']['long_name'] = 'Ocean Tide'
      L2_corr_attributes['ocTideElv']['description'] = ('Removes the effect of '
          'local tide and adjusts the measurement to the mean sea surface')
      L2_corr_attributes['ocTideElv']['units'] = 'millimeters'
      L2_corr_attributes['ocTideElv']['hertz'] = 1
      #-- Long period equilibrium ocean tide Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['lpeTideElv'] = {}
      L2_corr_attributes['lpeTideElv']['long_name'] = ('Long-Period Equilibrium '
          'Ocean Tide')
      L2_corr_attributes['lpeTideElv']['description'] = ('Removes the effect of '
          'local tide and adjusts the measurement to the mean sea surface')
      L2_corr_attributes['lpeTideElv']['units'] = 'millimeters'
      L2_corr_attributes['lpeTideElv']['hertz'] = 1
      #-- Ocean loading tide Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['olTideElv'] = {}
      L2_corr_attributes['olTideElv']['long_name'] = 'Ocean Loading Tide'
      L2_corr_attributes['olTideElv']['description'] = ('Removes the effect of '
          'local tidal distortion of the Earth crust')
      L2_corr_attributes['olTideElv']['units'] = 'millimeters'
      L2_corr_attributes['olTideElv']['hertz'] = 1
      #-- Solid Earth tide Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['seTideElv'] = {}
      L2_corr_attributes['seTideElv']['long_name'] = 'Solid Earth Tide'
      L2_corr_attributes['seTideElv']['description'] = ('Removes the effect of '
          'local tidal distortion in the Earth crust')
      L2_corr_attributes['seTideElv']['units'] = 'millimeters'
      L2_corr_attributes['seTideElv']['hertz'] = 1
      #-- Geocentric Polar tide Correction packed units (mm, 1e-3 m)
      L2_corr_attributes['gpTideElv'] = {}
      L2_corr_attributes['gpTideElv']['long_name'] = 'Geocentric Polar Tide'
      L2_corr_attributes['gpTideElv']['description'] = ('Removes a long-period '
          'distortion of the Earth crust caused by variations in the centrifugal '
          'force as the Earth rotational axis moves its geographic location')
      L2_corr_attributes['gpTideElv']['units'] = 'millimeters'
      L2_corr_attributes['gpTideElv']['hertz'] = 1
      #-- Surface Type: Packed in groups of three bits for each of the 20 records
      L2_corr_attributes['Surf_type'] = {}
      L2_corr_attributes['Surf_type']['long_name'] = 'Surface Type Flag'
      L2_corr_attributes['Surf_type']['description'] = ('Enumerated key to '
          'classify surface at nadir provided by a model: (0=Open Ocean, '
          '1=Closed Sea, 2=Continental Ice, 3=Land, 4-7=currently unused)')
      L2_corr_attributes['Surf_type']['hertz'] = 1
      #-- Ocean Depth/Land Elevation Model (ODLE) packed units (mm, 1e-3 m)
      L2_corr_attributes['ODLE'] = {}
      L2_corr_attributes['ODLE']['long_name'] = 'ODLE from model'
      L2_corr_attributes['ODLE']['description'] = ('Ocean Depth / Land Elevation'
          'model supplied in the Geophysical Corrections CFI library')
      L2_corr_attributes['ODLE']['units'] = 'millimeters'
      L2_corr_attributes['ODLE']['hertz'] = 1
      #-- Ice Concentration packed units (%/100)
      L2_corr_attributes['Ice_conc'] = {}
      L2_corr_attributes['Ice_conc']['long_name'] = 'Ice Concentration'
      L2_corr_attributes['Ice_conc']['description'] = ('Obtained from a dynamic '
          'auxiliary file if data is available for the current time period. '
          'If data is not available, a climatology model is used.')
      L2_corr_attributes['Ice_conc']['units'] = '1/100 of a percent'
      L2_corr_attributes['Ice_conc']['hertz'] = 1
      #-- Snow Depth packed units (mm, 1e-3 m)
      L2_corr_attributes['Snow_depth'] = {}
      L2_corr_attributes['Snow_depth']['long_name'] = 'Snow Depth'
      L2_corr_attributes['Snow_depth']['description'] = ('Obtained from'
          'climatology model data. Can be used to adjust the freeboard estimate '
          'to account for snow-loading.')
      L2_corr_attributes['Snow_depth']['units'] = 'millimeters'
      L2_corr_attributes['Snow_depth']['hertz'] = 1
      #-- Snow Density packed units (kg/m^3)
      L2_corr_attributes['Snow_density'] = {}
      L2_corr_attributes['Snow_density']['long_name'] = 'Snow Density'
      L2_corr_attributes['Snow_density']['description'] = ('Obtained from'
          'climatology model data. Can be used to adjust the freeboard estimate '
          'to account for snow-loading.')
      L2_corr_attributes['Snow_density']['units'] = 'kg/m^3'
      L2_corr_attributes['Snow_density']['hertz'] = 1
      #-- Corrections Status Flag
      L2_corr_attributes['C_status'] = {}
      L2_corr_attributes['C_status']['long_name'] = 'Corrections Status Flag'
      L2_corr_attributes['C_status']['description'] = ('Used to show validity of '
          'the 1Hz corrections.  See table 2.3.3.1-4 of the "L2 Products Format '
          'Specification" document')
      L2_corr_attributes['C_status']['hertz'] = 1
      #-- Significant Wave Height (SWH) packed units (mm, 1e-3)
      L2_corr_attributes['SWH'] = {}
      L2_corr_attributes['SWH']['long_name'] = 'Significant Wave Height (SWH)'
      L2_corr_attributes['SWH']['units'] = 'millimeters'
      L2_corr_attributes['SWH']['hertz'] = 1
      #-- Wind Speed packed units (mm/s, 1e-3 m/s)
      L2_corr_attributes['Wind_speed'] = {}
      L2_corr_attributes['Wind_speed']['long_name'] = 'Altimetric wind speed'
      L2_corr_attributes['Wind_speed']['description'] = ('Calculated using a '
          'model by the geocorrections CFI')
      L2_corr_attributes['Wind_speed']['units'] = 'mm/second'
      L2_corr_attributes['Wind_speed']['hertz'] = 1
      #-- Geoid height and mean sea surface for Baseline D
      if (BASELINE == 'D'):
          #-- Geoid: packed units (mm, 1e-3 m)
          L2_corr_attributes['Geoid'] = {}
          L2_corr_attributes['Geoid']['long_name'] = 'Geoid height'
          L2_corr_attributes['Geoid']['description'] = ('Computed from the geoid '
              'model with a correction to refer the value to the mean tide '
              'system. Includes permanent tide (zero frequency).')
          L2_corr_attributes['Geoid']['standard_name'] = ('geoid_height_above_'
              'reference_ellipsoid')
          L2_corr_attributes['Geoid']['units'] = 'millimeters'
          L2_corr_attributes['Geoid']['source'] = "EGM96"
          L2_corr_attributes['Geoid']['institution'] = "NASA GSFC and NIMA"
          L2_corr_attributes['Geoid']['reference'] = ('Lemoine, F. G., S. C. '
              'Kenyon, J. K. Factor, R.G. Trimmer, N. K. Pavlis, D. S. Chinn, '
              'C. M. Cox, S. M. Klosko, S. B. Luthcke, M. H. Torrence, Y. M. '
              'Wang, R. G. Williamson, E. C. Pavlis, R. H. Rapp and T. R. Olson. '
              'The Development of the Joint NASA GSFC and the National Imagery '
              'and Mapping Agency (NIMA) Geopotential Model EGM96. '
              'NASA/TP-1998-206861, July 1998.')
          L2_corr_attributes['Geoid']['hertz'] = 1
          #-- Mean Sea Surface: packed units (mm, 1e-3 m)
          L2_corr_attributes['MSS'] = {}
          L2_corr_attributes['MSS']['long_name'] = 'Mean sea surface height'
          L2_corr_attributes['MSS']['description'] = ('Mean sea surface model, '
              'referenced to the WGS84 ellipsoid. This model has been optimised '
              'for use in computing the surface height anomaly of the polar '
              'oceans to derive sea-ice freeboard. The model is a merge of the '
              'CLS2011 mean sea-surface and CryoSat data from high latitudes.')
          L2_corr_attributes['MSS']['standard_name'] = ('sea_surface_height_'
              'above_reference_ellipsoid')
          L2_corr_attributes['MSS']['units'] = 'millimeters'
          L2_corr_attributes['MSS']['source'] = "UCL13"
          L2_corr_attributes['MSS']['institution'] = "UCL"
          L2_corr_attributes['MSS']['hertz'] = 1
      else:
          #-- Mean Sea Surface or Geoid packed units (mm, 1e-3 m)
          L2_corr_attributes['MSS_Geoid'] = {}
          L2_corr_attributes['MSS_Geoid']['long_name']='Mean Sea Surface or Geoid'
          L2_corr_attributes['MSS_Geoid']['description'] = ('Over Ocean (Surface'
              'Types 0 and 1): surface height from the Mean Sea Surface. Over '
              'Land Surface Types 2 and 3): geoid height from the CFI library.')
          L2_corr_attributes['MSS_Geoid']['units'] = 'millimeters'
          L2_corr_attributes['MSS_Geoid']['hertz'] = 1
  
      #-- CryoSat-2 20 Hz data fields (Measurement Group)
      #-- Derived from instrument measurement parameters
      L2_20Hz_attributes = {}
      #-- Time: netCDF4 TAI time since 2000-01-01 00:00:00
      L2_20Hz_attributes['Time'] = {}
      L2_20Hz_attributes['Time']['long_name'] = 'MDSR time stamp'
      L2_20Hz_attributes['Time']['units'] = 'seconds since 2000-01-01 00:00:00.0'
      L2_20Hz_attributes['Time']['description'] = ('TAI time counted in seconds '
          'since 2000-01-01 00:00:00')
      L2_20Hz_attributes['Time']['hertz'] = 1
      L2_20Hz_attributes['Time']['calendar'] = 'gregorian'
      L2_20Hz_attributes['Time']['standard_name'] = 'time'
      #-- Delta between the timestamps for 20Hz record and the 1Hz record
      #-- D_time_mics packed units (microseconds)
      L2_20Hz_attributes['D_time_mics'] = {}
      L2_20Hz_attributes['D_time_mics']['long_name'] = 'Delta Time'
      L2_20Hz_attributes['D_time_mics']['description'] = ('Adds to the 1 Hz time '
          'stamp to give the correct time for each of the 20Hz measurement '
          '(Set to zero if block is partially empty)')
      L2_20Hz_attributes['D_time_mics']['units'] = 'microseconds'
      L2_20Hz_attributes['D_time_mics']['hertz'] = 20
      #-- Lat: packed units (0.1 micro-degree, 1e-7 degrees)
      L2_20Hz_attributes['Lat'] = {}
      L2_20Hz_attributes['Lat']['long_name'] = 'Latitude of measurement'
      L2_20Hz_attributes['Lat']['description'] = ('Measurement Latitude of the '
          'echoing point position.  Includes the x-track offset for SIN '
          'measurements and the slope-corrected position for LRM measurements.')
      L2_20Hz_attributes['Lat']['units'] = '0.1 micro-degree'
      L2_20Hz_attributes['Lat']['valid_min'] = -9e8
      L2_20Hz_attributes['Lat']['valid_max'] = 9e8
      L2_20Hz_attributes['Lat']['hertz'] = 20
      #-- Lon: packed units (0.1 micro-degree, 1e-7 degrees)
      L2_20Hz_attributes['Lon'] = {}
      L2_20Hz_attributes['Lon']['long_name'] = 'Longitude of measurement'
      L2_20Hz_attributes['Lon']['description'] = ('Measurement Longitude of the '
          'echoing point position.  Includes the x-track offset for SIN '
          'measurements and the slope-corrected position for LRM measurements.')
      L2_20Hz_attributes['Lon']['units'] = '0.1 micro-degree'
      L2_20Hz_attributes['Lon']['valid_min'] = -18e8
      L2_20Hz_attributes['Lon']['valid_max'] = 18e8
      L2_20Hz_attributes['Lon']['hertz'] = 20
  
      #-- Measured elevation and Backscatter (for 3 retrackers with Baseline-C,D)
      if (BASELINE == 'C'):
          #-- Measured elevation above ellipsoid from retracker 1
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev_1'] = {}
          L2_20Hz_attributes['Elev_1']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev_1']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev_1']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev_1']['retracker'] = 1
          L2_20Hz_attributes['Elev_1']['hertz'] = 20
          #-- Measured elevation above ellipsoid from retracker 2
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev_2'] = {}
          L2_20Hz_attributes['Elev_2']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev_2']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev_2']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev_2']['retracker'] = 2
          L2_20Hz_attributes['Elev_2']['hertz'] = 20
          #-- Measured elevation above ellipsoid from retracker 3
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev_3'] = {}
          L2_20Hz_attributes['Elev_3']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev_3']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev_3']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev_3']['retracker'] = 3
          L2_20Hz_attributes['Elev_3']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker 1: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0_1'] = {}
          L2_20Hz_attributes['Sig0_1']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0_1']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0_1']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0_1']['retracker'] = 1
          L2_20Hz_attributes['Sig0_1']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker 2: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0_2'] = {}
          L2_20Hz_attributes['Sig0_2']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0_2']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0_2']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0_2']['retracker'] = 2
          L2_20Hz_attributes['Sig0_2']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker 3: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0_3'] = {}
          L2_20Hz_attributes['Sig0_3']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0_3']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0_3']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0_3']['retracker'] = 3
          L2_20Hz_attributes['Sig0_3']['hertz'] = 20
      elif (BASELINE == 'D'):
          #-- Measured elevation above ellipsoid from retracker 1
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev_1'] = {}
          L2_20Hz_attributes['Elev_1']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev_1']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev_1']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev_1']['retracker'] = 1
          L2_20Hz_attributes['Elev_1']['hertz'] = 20
          #-- Measured elevation above ellipsoid from retracker 2
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev_2'] = {}
          L2_20Hz_attributes['Elev_2']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev_2']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev_2']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev_2']['retracker'] = 2
          L2_20Hz_attributes['Elev_2']['hertz'] = 20
          #-- Measured elevation above ellipsoid from retracker 3
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev_3'] = {}
          L2_20Hz_attributes['Elev_3']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev_3']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev_3']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev_3']['retracker'] = 3
          L2_20Hz_attributes['Elev_3']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker 1: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0_1'] = {}
          L2_20Hz_attributes['Sig0_1']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0_1']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0_1']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0_1']['retracker'] = 1
          L2_20Hz_attributes['Sig0_1']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker 2: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0_2'] = {}
          L2_20Hz_attributes['Sig0_2']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0_2']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0_2']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0_2']['retracker'] = 2
          L2_20Hz_attributes['Sig0_2']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker 3: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0_3'] = {}
          L2_20Hz_attributes['Sig0_3']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0_3']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0_3']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0_3']['retracker'] = 3
          L2_20Hz_attributes['Sig0_3']['hertz'] = 20
          #-- Measured range from the satellite to the surface from retracker 1
          L2_20Hz_attributes['Range_1'] = {}
          L2_20Hz_attributes['Range_1']['long_name'] = 'Range to surface'
          L2_20Hz_attributes['Range_1']['description'] =('Measured range from '
              'the satellite to the surface at the coordinate location. All '
              'instrumental corrections applied.  Does not include geophysical '
              'corrections.')
          L2_20Hz_attributes['Range_1']['units'] = 'mm'
          L2_20Hz_attributes['Range_1']['retracker'] = 1
          L2_20Hz_attributes['Range_1']['hertz'] = 20
          #-- Measured range from the satellite to the surface from retracker 2
          L2_20Hz_attributes['Range_2'] = {}
          L2_20Hz_attributes['Range_2']['long_name'] = 'Range to surface'
          L2_20Hz_attributes['Range_2']['description'] =('Measured range from '
              'the satellite to the surface at the coordinate location. All '
              'instrumental corrections applied.  Does not include geophysical '
              'corrections.')
          L2_20Hz_attributes['Range_2']['units'] = 'mm'
          L2_20Hz_attributes['Range_2']['retracker'] = 2
          L2_20Hz_attributes['Range_2']['hertz'] = 20
          #-- Measured range from the satellite to the surface from retracker 3
          L2_20Hz_attributes['Range_3'] = {}
          L2_20Hz_attributes['Range_3']['long_name'] = 'Range to surface'
          L2_20Hz_attributes['Range_3']['description'] = ('Measured range from '
              'the satellite to the surface at the coordinate location. All '
              'instrumental corrections applied.  Does not include geophysical '
              'corrections.')
          L2_20Hz_attributes['Range_3']['units'] = 'mm'
          L2_20Hz_attributes['Range_3']['retracker'] = 3
          L2_20Hz_attributes['Range_3']['hertz'] = 20
          #-- Sea ice Floe height
          L2_20Hz_attributes['Sea_Ice_Floe'] = {}
          L2_20Hz_attributes['Sea_Ice_Floe']['long_name'] = 'Sea ice Floe height'
          L2_20Hz_attributes['Sea_Ice_Floe']['description'] = ('Measured height '
              'of the surface above the reference ellipsoid (WGS84) at the '
              'coordinate location. This retracker is run over all surfaces not '
              'discriminated as a sea-ice lead, not just over sea-ice floes.')
          L2_20Hz_attributes['Sea_Ice_Floe']['units'] = 'mm'
          L2_20Hz_attributes['Sea_Ice_Floe']['retracker'] = 3
          L2_20Hz_attributes['Sea_Ice_Floe']['hertz'] = 20
          #-- Sea ice lead height
          L2_20Hz_attributes['Sea_Ice_Lead'] = {}
          L2_20Hz_attributes['Sea_Ice_Lead']['long_name'] = 'Sea ice lead height'
          L2_20Hz_attributes['Sea_Ice_Lead']['description'] = ('Measured height '
              'of the surface above the reference ellipsoid (WGS84) at the '
              'coordinate location. ')
          L2_20Hz_attributes['Sea_Ice_Lead']['units'] = 'mm'
          L2_20Hz_attributes['Sea_Ice_Lead']['retracker'] = 3
          L2_20Hz_attributes['Sea_Ice_Lead']['hertz'] = 20
      else:
          #-- Measured elevation above ellipsoid from retracker
          #-- packed units (mm, 1e-3 m)
          L2_20Hz_attributes['Elev'] = {}
          L2_20Hz_attributes['Elev']['long_name'] = 'Surface Elevation'
          L2_20Hz_attributes['Elev']['description'] = ('Height of surface at '
              'measurement point with respect to the reference ellipsoid (WGS84). '
              'It is calculated with the retracked and geocorrected range')
          L2_20Hz_attributes['Elev']['units'] = 'millimeters'
          L2_20Hz_attributes['Elev']['hertz'] = 20
          #-- Sigma Zero Backscatter for retracker: packed units (1e-2 dB)
          L2_20Hz_attributes['Sig0'] = {}
          L2_20Hz_attributes['Sig0']['long_name'] = 'Sigma Zero Backscatter'
          L2_20Hz_attributes['Sig0']['description'] = ('Fully corrected '
              'including instrument gain corrections and retracker correction')
          L2_20Hz_attributes['Sig0']['units'] = 'dB/100'
          L2_20Hz_attributes['Sig0']['hertz'] = 20
  
      #-- Freeboard: packed units (mm, 1e-3 m)
      #-- -9999 default value indicates computation has not been performed
      L2_20Hz_attributes['Freeboard'] = {}
      L2_20Hz_attributes['Freeboard']['long_name'] = 'Freeboard'
      L2_20Hz_attributes['Freeboard']['description'] = ('SAR mode computed '
          'freeboard of the Sea Ice. Freeboard can be a small negative value '
          'when there is sufficient snow loading on thin ice. Set to 0 in SIN '
          'and LRM modes.')
      L2_20Hz_attributes['Freeboard']['units'] = 'millimeters'
      L2_20Hz_attributes['Freeboard']['_FillValue'] = -9999
      L2_20Hz_attributes['Freeboard']['hertz'] = 20
      #-- Interpolated Sea Surface Height Anomaly: packed units (mm, 1e-3 m)
      L2_20Hz_attributes['SSHA_interp'] = {}
      L2_20Hz_attributes['SSHA_interp']['long_name'] = ('Interpolated Sea '
          'Surface Height Anomaly')
      L2_20Hz_attributes['SSHA_interp']['description'] = ('Ocean height anomaly '
          'defined by comparing the interpolated ocean height from the SAR '
          'processing with the MSS from the model')
      L2_20Hz_attributes['SSHA_interp']['units'] = 'millimeters'
      L2_20Hz_attributes['SSHA_interp']['hertz'] = 20
      #-- Interpolated Sea Surface Height measurement count
      L2_20Hz_attributes['SSHA_interp_count'] = {}
      L2_20Hz_attributes['SSHA_interp_count']['long_name'] = ('Interpolated Sea '
          'Surface Height measurement count')
      L2_20Hz_attributes['SSHA_interp_count']['description'] = ('Number of records used '
          'to create the fit in the SSHA calculation')
      L2_20Hz_attributes['SSHA_interp_count']['hertz'] = 20
      #-- Interpolation quality estimate RSS: packed units (mm, 1e-3 m)
      L2_20Hz_attributes['SSHA_interp_RMS'] = {}
      L2_20Hz_attributes['SSHA_interp_RMS']['long_name'] = ('Interpolated Sea '
          'Surface Height quality estimate')
      L2_20Hz_attributes['SSHA_interp_RMS']['description'] = ('Root mean square (RMS)'
          'of the residuals of the SSHA fit')
      L2_20Hz_attributes['SSHA_interp_RMS']['units'] = 'millimeters'
      L2_20Hz_attributes['SSHA_interp_RMS']['hertz'] = 20
      #-- Peakiness: packed units (1e-2)
      L2_20Hz_attributes['Peakiness'] = {}
      L2_20Hz_attributes['Peakiness']['long_name'] = 'Peakiness'
      L2_20Hz_attributes['Peakiness']['description'] = ('Peakiness of the echo '
          'in the L1b product. Requires different interpretation for SAR and SIN '
          'echoes which do not have the usual pulse-limited echo shape.')
      L2_20Hz_attributes['Peakiness']['units'] = '1/100'
      L2_20Hz_attributes['Peakiness']['hertz'] = 20
      #-- Number of averaged echoes or beams
      L2_20Hz_attributes['N_avg'] = {}
      L2_20Hz_attributes['N_avg']['long_name'] = 'Number of Echoes/Beams averaged'
      L2_20Hz_attributes['N_avg']['description'] = ('In LRM mode: number of '
          'echoes which have been averaged to make one measurement (normally). '
          'In SAR and SIN modes: number of Doppler beams which have been stacked '
          'to derive each measurement. Near the begining and end of each section '
          'of SAR or SIN mode operation, this number reduces below the nominal '
          'value and there is a corresponding decrease in the signal to noise '
          'ratio of the waveform.')
      L2_20Hz_attributes['N_avg']['hertz'] = 20
      #-- Quality flags
      L2_20Hz_attributes['Quality_flag'] = {}
      L2_20Hz_attributes['Quality_flag']['long_name'] = 'Measurement Quality Flags'
      L2_20Hz_attributes['Quality_flag']['description'] = ('Used to show validity '
          'of the 20Hz measurements.  See table 2.3.3.1-5 of the "L2 Products '
          'Format Specification" document')
      L2_20Hz_attributes['Quality_flag']['hertz'] = 20
  
      #-- Corrections Flag and Quality metrics for 3 retrackers with Baseline-C,D
      if (BASELINE == 'C'):
          #-- Corrections Application Flag
          L2_20Hz_attributes['Corrections_flag'] = {}
          L2_20Hz_attributes['Corrections_flag']['long_name'] = ('Corrections '
              'Application Flag')
          L2_20Hz_attributes['Corrections_flag']['hertz'] = 20
          #-- Quality metric for retracker 1
          L2_20Hz_attributes['Quality_1'] = {}
          L2_20Hz_attributes['Quality_1']['long_name'] = ('Quality metric for '
              'retracker')
          L2_20Hz_attributes['Quality_1']['retracker'] = 1
          L2_20Hz_attributes['Quality_1']['hertz'] = 20
          #-- Quality metric for retracker 2
          L2_20Hz_attributes['Quality_2'] = {}
          L2_20Hz_attributes['Quality_2']['long_name'] = ('Quality metric for '
              'retracker')
          L2_20Hz_attributes['Quality_2']['retracker'] = 2
          L2_20Hz_attributes['Quality_2']['hertz'] = 20
          #-- Quality metric for retracker 3
          L2_20Hz_attributes['Quality_3'] = {}
          L2_20Hz_attributes['Quality_3']['long_name'] = ('Quality metric for '
              'retracker')
          L2_20Hz_attributes['Quality_3']['retracker'] = 3
          L2_20Hz_attributes['Quality_3']['hertz'] = 20
      elif (BASELINE == 'D'):
          #-- Corrections Application Flag
          L2_20Hz_attributes['Corrections_flag'] = {}
          L2_20Hz_attributes['Corrections_flag']['long_name'] = ('Corrections '
              'Application Flag')
          L2_20Hz_attributes['Corrections_flag']['hertz'] = 20
          #-- Measurement mode
          L2_20Hz_attributes['Measurement_Mode'] = {}
          L2_20Hz_attributes['Measurement_Mode']['long_name'] = ('Instrument '
              'measurement mode derived from configuration bits in L0')
          L2_20Hz_attributes['Measurement_Mode']['flag_values'] = [1,2,3]
          L2_20Hz_attributes['Measurement_Mode']['flag_meanings']='lrm sar sarin'
          L2_20Hz_attributes['Measurement_Mode']['hertz'] = 20
          #-- Surface Type
          L2_20Hz_attributes['Surf_type'] = {}
          L2_20Hz_attributes['Surf_type']['long_name'] = 'surface type from mask'
          L2_20Hz_attributes['Surf_type']['description'] = ('A 4-state surface '
              'type mask for Cryosat2 data for the surface type at the nadir '
              'location. Computed by combining data from different sources: '
              'GSHHG, GlobCover, MODIS Mosaic of Antarctica, and Water body '
              'outlines from LEGOS')
          L2_20Hz_attributes['Surf_type']['flag_values'] = [0,1,2,3]
          L2_20Hz_attributes['Surf_type']['flag_meanings'] = ('ocean '
              'lake_enclosed_sea ice land')
          L2_20Hz_attributes['Surf_type']['source'] = ('GSHHG, GlobCover, '
              'MODIS Mosaic of Antarctica, and Water body outlines from LEGOS')
          L2_20Hz_attributes['Surf_type']['hertz'] = 20
          #-- Quality metric for retracker 1
          L2_20Hz_attributes['Quality_1'] = {}
          L2_20Hz_attributes['Quality_1']['long_name'] = ('Quality metric for '
              'retracker')
          L2_20Hz_attributes['Quality_1']['retracker'] = 1
          L2_20Hz_attributes['Quality_1']['hertz'] = 20
          #-- Quality metric for retracker 2
          L2_20Hz_attributes['Quality_2'] = {}
          L2_20Hz_attributes['Quality_2']['long_name'] = ('Quality metric for '
              'retracker')
          L2_20Hz_attributes['Quality_2']['retracker'] = 2
          L2_20Hz_attributes['Quality_2']['hertz'] = 20
          #-- Quality metric for retracker 3
          L2_20Hz_attributes['Quality_3'] = {}
          L2_20Hz_attributes['Quality_3']['long_name'] = ('Quality metric for '
              'retracker')
          L2_20Hz_attributes['Quality_3']['retracker'] = 3
          L2_20Hz_attributes['Quality_3']['hertz'] = 20
  
      #-- Bind all the l2 attributes together into single dictionary
      CS_l2_attrib = {}
      CS_l2_attrib['Data_1Hz'] = L2_1Hz_attributes
      CS_l2_attrib['Corrections'] = L2_corr_attributes
      CS_l2_attrib['Data_20Hz'] = L2_20Hz_attributes
      #-- return the output dictionary
      return CS_l2_attrib
  