Exemplo n.º 1
0
def getATL03data(fileT, numpyout=False, beam='gt1l'):
    """ Pandas/numpy ATL03 reader
    Written by Alek Petty, June 2018 ([email protected])

    I've picked out the variables from ATL03 I think are of most interest to sea ice users, but by no
    means is this an exhastive list. 
    See the xarray or dictionary readers to load in the more complete ATL03 dataset
    or explore the hdf5 files themselves (I like using the app Panpoly for this) to see what else you
    might want
    
    Args:
        fileT (str): File path of the ATL03 dataset
        numpy (flag): Binary flag for outputting numpy arrays (True) or pandas dataframe (False)
        beam (str): ICESat-2 beam (the number is the pair, r=strong, l=weak)
        
    returns:
        either: select numpy arrays or a pandas dataframe

    """

    # Open the file
    try:
        ATL03 = h5py.File(fileT, 'r')
    except:
        'Not a valid file'

    lons = ATL03[beam + '/heights/lon_ph'][:]
    lats = ATL03[beam + '/heights/lat_ph'][:]

    #  Number of seconds since the GPS epoch on midnight Jan. 6, 1980
    delta_time = ATL03[beam + '/heights/delta_time'][:]

    # #Add this value to delta time parameters to compute the full gps_seconds
    atlas_epoch = ATL03['/ancillary_data/atlas_sdp_gps_epoch'][:]

    # Conversion of delta_time to a calendar date
    # This function seems pretty convoluted but it works for now..Sure there is a simpler functionw e can use here instead.
    temp = ut.convert_GPS_time(atlas_epoch[0] + delta_time, OFFSET=0.0)

    # Express delta_time relative to start time of granule
    delta_time_granule = delta_time - delta_time[0]

    year = temp['year'][:].astype('int')
    month = temp['month'][:].astype('int')
    day = temp['day'][:].astype('int')
    hour = temp['hour'][:].astype('int')
    minute = temp['minute'][:].astype('int')
    second = temp['second'][:].astype('int')

    dFtime = pd.DataFrame({
        'year': year,
        'month': month,
        'day': day,
        'hour': hour,
        'minute': minute,
        'second': second
    })

    # Primary variables of interest

    # Photon height
    heights = ATL03[beam + '/heights/h_ph'][:]
    print(heights.shape)

    # Flag for signal confidence
    # column index:  0=Land; 1=Ocean; 2=SeaIce; 3=LandIce; 4=InlandWater
    # values:
    #-- -1: Events not associated with a specific surface type
    #--  0: noise
    #--  1: buffer but algorithm classifies as background
    #--  2: low
    #--  3: medium
    #--  4: high
    signal_confidence = ATL03[beam + '/heights/signal_conf_ph'][:, 2]

    # Add photon rate, background rate etc to the reader here if we want

    ATL03.close()

    dF = pd.DataFrame({
        'heights': heights,
        'lons': lons,
        'lats': lats,
        'signal_confidence': signal_confidence,
        'delta_time': delta_time_granule
    })

    # Add the datetime string
    dFtimepd = pd.to_datetime(dFtime)
    dF['datetime'] = pd.Series(dFtimepd, index=dF.index)

    # Filter out high elevation values
    #dF = dF[(dF['signal_confidence']>2)]
    # Reset row indexing
    #dF=dF.reset_index(drop=True)
    return dF
Exemplo n.º 2
0
def getATL10data(fileT, beam='gt1r', maxFreeboard=10):
    """ Pandas/numpy ATL10 reader
    Written by Alek Petty, June 2018 ([email protected])

	I've picked out the variables from ATL10 I think are of most interest to sea ice users, 
    but by no means is this an exhastive list. 
    See the xarray or dictionary readers to load in the more complete ATL10 dataset
    or explore the hdf5 files themselves (I like using the app Panpoly for this) to see what else you might want
    
	Args:
		fileT (str): File path of the ATL10 dataset
		beamStr (str): ICESat-2 beam (the number is the pair, r=strong, l=weak)
        maxFreeboard (float): maximum freeboard (meters)

	returns:
        pandas dataframe

	"""

    print('ATL10 file:', fileT)

    f1 = h5py.File(fileT, 'r')

    freeboard = f1[beam]['freeboard_beam_segment']['beam_freeboard'][
        'beam_fb_height'][:]

    freeboard_confidence = f1[beam]['freeboard_beam_segment'][
        'beam_freeboard']['beam_fb_confidence'][:]
    freeboard_quality = f1[beam]['freeboard_beam_segment']['beam_freeboard'][
        'beam_fb_quality_flag'][:]

    lons = f1[beam]['freeboard_beam_segment']['beam_freeboard']['longitude'][:]
    lats = f1[beam]['freeboard_beam_segment']['beam_freeboard']['latitude'][:]
    deltaTime = f1[beam]['freeboard_beam_segment']['beam_freeboard'][
        'delta_time'][:] - f1[beam]['freeboard_beam_segment'][
            'beam_freeboard']['delta_time'][0]

    # #Add this value to delta time parameters to compute full gps_seconds
    atlas_epoch = f1['/ancillary_data/atlas_sdp_gps_epoch'][:]

    # Conversion of delta_time to a calendar date
    temp = ut.convert_GPS_time(atlas_epoch[0] + deltaTime, OFFSET=0.0)

    year = temp['year'][:].astype('int')
    month = temp['month'][:].astype('int')
    day = temp['day'][:].astype('int')
    hour = temp['hour'][:].astype('int')
    minute = temp['minute'][:].astype('int')
    second = temp['second'][:].astype('int')
    dFtime = pd.DataFrame({
        'year': year,
        'month': month,
        'day': day,
        'hour': hour,
        'minute': minute,
        'second': second
    })

    dF = pd.DataFrame({
        'freeboard': freeboard,
        'lon': lons,
        'lat': lats,
        'delta_time': deltaTime,
        'year': year,
        'month': month,
        'day': day
    })

    dFtimepd = pd.to_datetime(dFtime)
    dF['datetime'] = pd.Series(dFtimepd, index=dF.index)

    dF = dF[(dF['freeboard'] > 0)]
    dF = dF[(dF['freeboard'] < maxFreeboard)]
    # Decide here if we want to also filter based on the confidence and/or quality flag

    # Reset row indexing
    dF = dF.reset_index(drop=True)

    return dF
Exemplo n.º 3
0
def getATL07data(fileT, numpy=False, beam='gt1r', maxElev=1e6):
    """ Pandas/numpy ATL07 reader
    Written by Alek Petty, June 2018 ([email protected])

	I've picked out the variables from ATL07 I think are of most interest to sea ice users, but by no means is this an exhastive list. 
    See the xarray or dictionary readers to load in the more complete ATL07 dataset
    or explore the hdf5 files themselves (I like using the app Panpoly for this) to see what else you might want
    
	Args:
		fileT (str): File path of the ATL07 dataset
		numpy (flag): Binary flag for outputting numpy arrays (True) or pandas dataframe (False)
		beam (str): ICESat-2 beam (the number is the pair, r=strong, l=weak)
        maxElev (float): maximum surface elevation to remove anomalies

	returns:
		either: select numpy arrays or a pandas dataframe

	"""

    # Open the file
    try:
        ATL07 = h5py.File(fileT, 'r')
    except:
        return 'Not a valid file'

    lons = ATL07[beam + '/sea_ice_segments/longitude'][:]
    lats = ATL07[beam + '/sea_ice_segments/latitude'][:]

    # Along track distance from the equator crossing to the segment center.
    # I removed the first point so it's relative to the start of the beam
    along_track_distance = ATL07[beam +
                                 '/sea_ice_segments/seg_dist_x'][:] - ATL07[
                                     beam + '/sea_ice_segments/seg_dist_x'][0]
    # Height segment ID (10 km segments)
    height_segment_id = ATL07[beam + '/sea_ice_segments/height_segment_id'][:]
    #  Nathan says it's the number of seconds since the GPS epoch on midnight Jan. 6, 1980
    delta_time = ATL07[beam + '/sea_ice_segments/delta_time'][:]
    # #Add this value to delta time parameters to compute full gps_seconds
    atlas_epoch = ATL07['/ancillary_data/atlas_sdp_gps_epoch'][:]

    # Conversion of delta_time to a calendar date
    temp = ut.convert_GPS_time(atlas_epoch[0] + delta_time, OFFSET=0.0)

    year = temp['year'][:].astype('int')
    month = temp['month'][:].astype('int')
    day = temp['day'][:].astype('int')
    hour = temp['hour'][:].astype('int')
    minute = temp['minute'][:].astype('int')
    second = temp['second'][:].astype('int')

    dFtime = pd.DataFrame({
        'year': year,
        'month': month,
        'day': day,
        'hour': hour,
        'minute': minute,
        'second': second
    })

    # Primary variables of interest

    # Beam segment height
    elev = ATL07[beam + '/sea_ice_segments/heights/height_segment_height'][:]
    # Flag for potential leads, 0=sea ice, 1 = sea surface
    ssh_flag = ATL07[beam +
                     '/sea_ice_segments/heights/height_segment_ssh_flag'][:]

    #Quality metrics for each segment include confidence level in the surface height estimate,
    # which is based on the number of photons, the background noise rate, and the error measure provided by the surface-finding algorithm.
    # Height quality flag, 1 for good fit, 0 for bad
    quality = ATL07[beam +
                    '/sea_ice_segments/heights/height_segment_quality'][:]

    elev_rms = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_rms'][:]  #RMS difference between modeled and observed photon height distribution
    seg_length = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_length_seg'][:]  # Along track length of segment
    height_confidence = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_confidence'][:]  # Height segment confidence flag
    reflectance = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_asr_calc'][:]  # Apparent surface reflectance
    ssh_flag = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_ssh_flag'][:]  # Flag for potential leads, 0=sea ice, 1 = sea surface
    seg_type = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_type'][:]  # 0 = Cloud covered
    gauss_width = ATL07[
        beam +
        '/sea_ice_segments/heights/height_segment_w_gaussian'][:]  # Width of Gaussian fit

    # Geophysical corrections
    # NOTE: All of these corrections except ocean tides, DAC,
    # and geoid undulations are applied to the ATL03 photon heights.

    # AVISO dynamic Atmospheric Correction (DAC) including inverted barometer (IB) effect (±5cm)
    dac = ATL07[beam + '/sea_ice_segments/geophysical/height_segment_dac'][:]
    # Solid Earth Tides (±40 cm, max)
    earth = ATL07[beam +
                  '/sea_ice_segments/geophysical/height_segment_earth'][:]
    # Geoid (-105 to +90 m, max)
    geoid = ATL07[beam +
                  '/sea_ice_segments/geophysical/height_segment_geoid'][:]
    # Local displacement due to Ocean Loading (-6 to 0 cm)
    loadTide = ATL07[beam +
                     '/sea_ice_segments/geophysical/height_segment_load'][:]
    # Ocean Tides including diurnal and semi-diurnal (harmonic analysis),
    # and longer period tides (dynamic and self-consistent equilibrium) (±5 m)
    oceanTide = ATL07[beam +
                      '/sea_ice_segments/geophysical/height_segment_ocean'][:]
    # Deformation due to centrifugal effect from small variations in polar motion
    # (Solid Earth Pole Tide) (±1.5 cm, the ocean pole tide ±2mm amplitude is considered negligible)
    poleTide = ATL07[beam +
                     '/sea_ice_segments/geophysical/height_segment_pole'][:]
    # Mean sea surface (±2 m)
    # Taken from ICESat and CryoSat-2, see Kwok and Morison [2015])
    mss = ATL07[beam + '/sea_ice_segments/geophysical/height_segment_mss'][:]

    photon_rate = ATL07[beam + '/sea_ice_segments/stats/photon_rate'][:]
    background_rate = ATL07[beam + '/sea_ice_segments/stats/backgr_calc'][:]

    ATL07.close()

    if numpy:
        # list the variables you want to output here..
        return along_track_dist, elev

    else:
        dF = pd.DataFrame({
            'elev': elev,
            'lons': lons,
            'lats': lats,
            'ssh_flag': ssh_flag,
            'quality_flag': quality,
            'delta_time': delta_time,
            'along_track_distance': along_track_distance,
            'height_segment_id': height_segment_id,
            'photon_rate': photon_rate,
            'background_rate': background_rate
        })

        # Add the datetime string
        dFtimepd = pd.to_datetime(dFtime)
        dF['datetime'] = pd.Series(dFtimepd, index=dF.index)

        # Filter out high elevation values
        dF = dF[(dF['elev'] < maxElev)]
        # Reset row indexing
        dF = dF.reset_index(drop=True)
        return dF