예제 #1
0
def skip_files_with_inconsistent_size(dsPathDict,
                                      pix_box=None,
                                      dsName='unwrapPhase'):
    """Skip files by removing the file path from the input dsPathDict."""
    atr_list = [readfile.read_attribute(fname) for fname in dsPathDict[dsName]]
    length_list = [int(atr['LENGTH']) for atr in atr_list]
    width_list = [int(atr['WIDTH']) for atr in atr_list]

    # Check size requirements
    drop_inconsistent_files = False
    if any(len(set(size_list)) > 1 for size_list in [length_list, width_list]):
        if pix_box is None:
            drop_inconsistent_files = True
        else:
            # if input subset is within the min file sizes: do NOT drop
            max_box_width, max_box_length = pix_box[2:4]
            if max_box_length > min(length_list) or max_box_width > min(
                    width_list):
                drop_inconsistent_files = True

    # update dsPathDict
    if drop_inconsistent_files:
        common_length = ut.most_common(length_list)
        common_width = ut.most_common(width_list)

        # print out warning message
        msg = '\n' + '*' * 80
        msg += '\nWARNING: NOT all input unwrapped interferograms have the same row/column number!'
        msg += '\nThe most common size is: ({}, {})'.format(
            common_length, common_width)
        msg += '\n' + '-' * 30
        msg += '\nThe following dates have different size:'

        dsNames = list(dsPathDict.keys())
        date12_list = [atr['DATE12'] for atr in atr_list]
        num_drop = 0
        for i in range(len(date12_list)):
            if length_list[i] != common_length or width_list[i] != common_width:
                date12 = date12_list[i]
                dates = ptime.yyyymmdd(date12.split('-'))
                # update file list for all datasets
                for dsName in dsNames:
                    fnames = [
                        i for i in dsPathDict[dsName]
                        if all(d[2:8] in i for d in dates)
                    ]
                    if len(fnames) > 0:
                        dsPathDict[dsName].remove(fnames[0])
                msg += '\n\t{}\t({}, {})'.format(date12, length_list[i],
                                                 width_list[i])
                num_drop += 1

        msg += '\n' + '-' * 30
        msg += '\nSkip loading the above interferograms ({}).'.format(num_drop)
        msg += '\nContinue to load the rest interferograms ({}).'.format(
            len(date12_list) - num_drop)
        msg += '\n' + '*' * 80 + '\n'
        print(msg)
    return dsPathDict
예제 #2
0
def check_exist_grib_file(gfile_list, print_msg=True):
    """Check input list of grib files, and return the existing ones with right size."""
    gfile_exist = ut.get_file_list(gfile_list)
    if gfile_exist:
        file_sizes = [os.path.getsize(i) for i in gfile_exist
                      if os.path.getsize(i) > 10e6]
        if file_sizes:
            comm_size = ut.most_common([i for i in file_sizes])
            if print_msg:
                print('common file size: {} bytes'.format(comm_size))
                print('number of grib files existed    : {}'.format(len(gfile_exist)))

            gfile_corrupt = []
            for gfile in gfile_exist:
                if os.path.getsize(gfile) < comm_size * 0.9:
                    gfile_corrupt.append(gfile)
        else:
            gfile_corrupt = gfile_exist

        if gfile_corrupt:
            if print_msg:
                print('------------------------------------------------------------------------------')
                print('corrupted grib files detected! Delete them and re-download...')
                print('number of grib files corrupted  : {}'.format(len(gfile_corrupt)))
            for i in gfile_corrupt:
                rmCmd = 'rm '+i
                print(rmCmd)
                os.system(rmCmd)
                gfile_exist.remove(i)
            if print_msg:
                print('------------------------------------------------------------------------------')
    return gfile_exist
예제 #3
0
def check_exist_grib_file(gfile_list, print_msg=True):
    """Check input list of grib files, and return the existing ones with right size."""
    gfile_exist = ut.get_file_list(gfile_list)
    if gfile_exist:
        file_sizes = [os.path.getsize(i) for i in gfile_exist] # if os.path.getsize(i) > 10e6]
        if file_sizes:
            comm_size = ut.most_common([i for i in file_sizes])
            if print_msg:
                print('common file size: {} bytes'.format(comm_size))
                print('number of grib files existed    : {}'.format(len(gfile_exist)))

            gfile_corrupt = []
            for gfile in gfile_exist:
                if os.path.getsize(gfile) < comm_size * 0.9:
                    gfile_corrupt.append(gfile)
        else:
            gfile_corrupt = gfile_exist

        if gfile_corrupt:
            if print_msg:
                print('------------------------------------------------------------------------------')
                print('corrupted grib files detected! Delete them and re-download...')
                print('number of grib files corrupted  : {}'.format(len(gfile_corrupt)))
            for i in gfile_corrupt:
                rmCmd = 'rm '+i
                print(rmCmd)
                os.system(rmCmd)
                gfile_exist.remove(i)
            if print_msg:
                print('------------------------------------------------------------------------------')
    return gfile_exist
예제 #4
0
def safe2date_time(safe_file, tropo_model):
    """generate date_list and hour from safe_list"""
    def seconds_UTC(seconds):
        """generate second list"""
        if isinstance(seconds, list):
            secondsOut = []
            for second in seconds:
                secondsOut.append(second)
        else:
            print('\nUn-recognized CENTER_LINE_UTC input!')
            return None

        return secondsOut

    date_list = ptime.yyyymmdd(
        np.loadtxt(safe_file, dtype=bytes, converters={
            0: define_date
        }).astype(str).tolist())
    second_list = seconds_UTC(
        np.loadtxt(safe_file, dtype=bytes, converters={
            0: define_second
        }).astype(str).tolist())

    # change second into hour
    hour_list = [
        closest_weather_model_hour(float(second), tropo_model)
        for second in second_list
    ]
    hour = ut.most_common(hour_list)

    return date_list, hour
예제 #5
0
def download_igs_tec(date_list, tec_dir, tec_sol='jpl'):
    """Download IGS TEC products for the input list of dates.

    Parameters: date_list - list of str, in YYYYMMDD
                tec_dir   - str, path to IGS_TEC directory, e.g. ~/data/aux/IGS_TEC
                tec_sol   - str, TEC solution center, e.g. jpl, cod, igs
    Returns:    fnames    - list of str, path of the downloaded TEC files
    """
    print("\n------------------------------------------------------------------------------")
    print("downloading GNSS-based TEC products from NASA's Archive of Space Geodesy Data (CDDIS) ...")
    print('Link: https://cddis.nasa.gov/Data_and_Derived_Products/GNSS/atmospheric_products.html')
    num_date = len(date_list)
    n = len(str(num_date))
    print(f'number of TEC files to download: {num_date}')
    print(f'local TEC file directory: {tec_dir}')

    # output file names/sizes
    fnames = []
    for date_str in date_list:
        fnames.append(iono.get_igs_tec_filename(tec_dir, date_str, sol=tec_sol))

    # remove all existing files
    debug_mode = False
    if debug_mode:
        for fname in fnames:
            for x in [fname, fname+'.Z']:
                if os.path.isfile(x):
                    os.remove(x)

    fsizes = [os.path.getsize(i) / 1024 if os.path.isfile(i) else 0 for i in fnames]

    # download: skip existing ones
    fsizec = ut.most_common(fsizes)
    if fsizec < 400:
        # too small, does not seem right --> download them all
        date_list2dload = list(date_list)

    else:
        # download missing ones
        date_list2dload = [d for d, s in zip(date_list, fsizes) if s < fsizec * 0.9]

    num_date2dload = len(date_list2dload)
    if num_date2dload == 0:
        print(f'ALL files exists with consistent file size (~{fsizec:.0f} KB) --> skip re-downloading.\n')

    else:
        for i, date_str in enumerate(date_list2dload):
            print('-'*20)
            print('DATE {}/{}: {}'.format(i+1, num_date2dload, date_str))
            iono.dload_igs_tec(date_str, tec_dir, sol=tec_sol, print_msg=True)

        # print file size info, after downloading
        fsizes = [os.path.getsize(i) / 1024 if os.path.isfile(i) else 0 for i in fnames]
        for i in range(num_date):
            print('[{i:0{n}d}/{N}] {f}: {s:.2f} KB'.format(n=n, i=i+1, N=num_date, f=fnames[i], s=fsizes[i]))

    return fnames
예제 #6
0
def read_baseline_timeseries(baseline_dir, processor='tops'):
    """Read bperp time-series from files in baselines directory
    Parameters: baseline_dir : str, path to the baselines directory
                processor    : str, tops     for Sentinel-1/TOPS
                                    stripmap for StripMap data
    Returns:    bDict : dict, in the following format:
                    {'20141213': [0.0, 0.0],
                     '20141225': [104.6, 110.1],
                     ...
                    }
    """
    print('read perp baseline time-series from {}'.format(baseline_dir))
    # grab all existed baseline files
    if processor == 'tops':
        bFiles = sorted(glob.glob(os.path.join(baseline_dir, '*/*.txt')))
    elif processor == 'stripmap':
        bFiles = sorted(glob.glob(os.path.join(baseline_dir, '*.txt')))
    else:
        raise ValueError(
            'Un-recognized ISCE stack processor: {}'.format(processor))
    if len(bFiles) == 0:
        print('WARNING: no baseline text file found in dir {}'.format(
            os.path.abspath(baseline_dir)))
        return None

    # ignore files with different date1
    # when re-run with different reference date
    date1s = [os.path.basename(i).split('_')[0] for i in bFiles]
    date1 = ut.most_common(date1s)
    bFiles = [i for i in bFiles if os.path.basename(i).split('_')[0] == date1]

    # read files into dict
    bDict = {}
    for bFile in bFiles:
        dates = os.path.basename(bFile).split('.txt')[0].split('_')
        if processor == 'tops':
            bDict[dates[1]] = read_tops_baseline(bFile)
        else:
            bDict[dates[1]] = read_stripmap_baseline(bFile)
    bDict[dates[0]] = [0, 0]
    return bDict
예제 #7
0
def plot_rms_bar(ax,
                 date_list,
                 rms,
                 cutoff=3.,
                 font_size=12,
                 tick_year_num=1,
                 legend_loc='best',
                 disp_legend=True,
                 disp_side_plot=True,
                 disp_thres_text=False,
                 ylabel=r'Residual Phase $\hat \phi_{resid}$ RMS [mm]'):
    """ Bar plot Phase Residual RMS
    Parameters: ax : Axes object
                date_list : list of string in YYYYMMDD format
                rms    : 1D np.array of float for RMS value in mm
                cutoff : cutoff value of MAD outlier detection
                tick_year_num : int, number of years per major tick
                legend_loc : 'upper right' or (0.5, 0.5)
    Returns:    ax : Axes object
    """
    dates, datevector = ptime.date_list2vector(date_list)
    dates = np.array(dates)
    try:
        bar_width = min(ut.most_common(np.diff(dates).tolist(), k=2)) * 3 / 4
    except:
        bar_width = np.min(np.diff(dates).tolist()) * 3 / 4
    rms = np.array(rms)

    # Plot all dates
    ax.bar(dates, rms, bar_width.days, color=pp.mplColors[0])

    # Plot reference date
    ref_idx = np.argmin(rms)
    ax.bar(dates[ref_idx],
           rms[ref_idx],
           bar_width.days,
           color=pp.mplColors[1],
           label='Reference date')

    # Plot exclude dates
    rms_threshold = ut.median_abs_deviation_threshold(rms,
                                                      center=0.,
                                                      cutoff=cutoff)
    ex_idx = rms > rms_threshold
    if not np.all(ex_idx == False):
        ax.bar(dates[ex_idx],
               rms[ex_idx],
               bar_width.days,
               color='darkgray',
               label='Exclude date')

    # Plot rms_threshold line
    (ax, xmin, xmax) = pp.auto_adjust_xaxis_date(ax,
                                                 datevector,
                                                 font_size,
                                                 every_year=tick_year_num)
    ax.plot(np.array([xmin, xmax]),
            np.array([rms_threshold, rms_threshold]),
            '--k',
            label='Median Abs Dev * {}'.format(cutoff))

    # axis format
    ax = pp.auto_adjust_yaxis(ax,
                              np.append(rms, rms_threshold),
                              font_size,
                              ymin=0.0)
    ax.set_xlabel('Time [years]', fontsize=font_size)
    ax.set_ylabel(ylabel, fontsize=font_size)
    ax.tick_params(which='both',
                   direction='in',
                   labelsize=font_size,
                   bottom=True,
                   top=True,
                   left=True,
                   right=True)

    # 2nd axes for circles
    if disp_side_plot:
        divider = make_axes_locatable(ax)
        ax2 = divider.append_axes("right", "10%", pad="2%")
        ax2.plot(np.ones(rms.shape, np.float32) * 0.5,
                 rms,
                 'o',
                 mfc='none',
                 color=pp.mplColors[0])
        ax2.plot(np.ones(rms.shape, np.float32)[ref_idx] * 0.5,
                 rms[ref_idx],
                 'o',
                 mfc='none',
                 color=pp.mplColors[1])
        if not np.all(ex_idx == False):
            ax2.plot(np.ones(rms.shape, np.float32)[ex_idx] * 0.5,
                     rms[ex_idx],
                     'o',
                     mfc='none',
                     color='darkgray')
        ax2.plot(np.array([0, 1]), np.array([rms_threshold, rms_threshold]),
                 '--k')

        ax2.set_ylim(ax.get_ylim())
        ax2.set_xlim([0, 1])
        ax2.tick_params(which='both',
                        direction='in',
                        labelsize=font_size,
                        bottom=True,
                        top=True,
                        left=True,
                        right=True)
        ax2.get_xaxis().set_ticks([])
        ax2.get_yaxis().set_ticklabels([])

    if disp_legend:
        ax.legend(loc=legend_loc, frameon=False, fontsize=font_size)

    # rms_threshold text
    if disp_thres_text:
        ymin, ymax = ax.get_ylim()
        yoff = (ymax - ymin) * 0.1
        if (rms_threshold - ymin) > 0.5 * (ymax - ymin):
            yoff *= -1.
        ax.annotate('Median Abs Dev * {}'.format(cutoff),
                    xy=(xmin + (xmax - xmin) * 0.05, rms_threshold + yoff),
                    color='k',
                    xycoords='data',
                    fontsize=font_size)
    return ax
예제 #8
0
def plot_rms_bar(ax, date_list, rms, cutoff=3., font_size=12, 
                 tick_year_num=1, legend_loc='best',
                 disp_legend=True, disp_side_plot=True, disp_thres_text=True,
                 ylabel=r'Residual Phase $\hat \phi_{resid}$ RMS [mm]'):
    """ Bar plot Phase Residual RMS
    Parameters: ax : Axes object
                date_list : list of string in YYYYMMDD format
                rms    : 1D np.array of float for RMS value in mm
                cutoff : cutoff value of MAD outlier detection
                tick_year_num : int, number of years per major tick
                legend_loc : 'upper right' or (0.5, 0.5)
    Returns:    ax : Axes object
    """
    dates, datevector = ptime.date_list2vector(date_list)
    dates = np.array(dates)
    try:
        bar_width = min(ut.most_common(np.diff(dates).tolist(), k=2))*3/4
    except:
        bar_width = np.min(np.diff(dates).tolist())*3/4
    rms = np.array(rms)

    # Plot all dates
    ax.bar(dates, rms, bar_width.days, color=pp.mplColors[0])

    # Plot reference date
    ref_idx = np.argmin(rms)
    ax.bar(dates[ref_idx], rms[ref_idx], bar_width.days, color=pp.mplColors[1], label='Reference date')

    # Plot exclude dates
    rms_threshold = ut.median_abs_deviation_threshold(rms, center=0., cutoff=cutoff)
    ex_idx = rms > rms_threshold
    if not np.all(ex_idx==False):
        ax.bar(dates[ex_idx], rms[ex_idx], bar_width.days, color='darkgray', label='Exclude date')

    # Plot rms_threshold line
    (ax, xmin, xmax) = pp.auto_adjust_xaxis_date(ax, datevector, font_size, every_year=tick_year_num)
    ax.plot(np.array([xmin, xmax]), np.array([rms_threshold, rms_threshold]), '--k', label='RMS threshold')

    # axis format
    ax = pp.auto_adjust_yaxis(ax, np.append(rms, rms_threshold), font_size, ymin=0.0)
    ax.set_xlabel('Time [years]', fontsize=font_size)
    ax.set_ylabel(ylabel, fontsize=font_size)
    ax.tick_params(which='both', direction='in', labelsize=font_size,
                   bottom=True, top=True, left=True, right=True)

    # 2nd axes for circles
    if disp_side_plot:
        divider = make_axes_locatable(ax)
        ax2 = divider.append_axes("right", "10%", pad="2%")
        ax2.plot(np.ones(rms.shape, np.float32) * 0.5, rms, 'o', mfc='none', color=pp.mplColors[0])
        ax2.plot(np.ones(rms.shape, np.float32)[ref_idx] * 0.5, rms[ref_idx], 'o', mfc='none', color=pp.mplColors[1])
        if not np.all(ex_idx==False):
            ax2.plot(np.ones(rms.shape, np.float32)[ex_idx] * 0.5, rms[ex_idx], 'o', mfc='none', color='darkgray')
        ax2.plot(np.array([0, 1]), np.array([rms_threshold, rms_threshold]), '--k')

        ax2.set_ylim(ax.get_ylim())
        ax2.set_xlim([0, 1])
        ax2.tick_params(which='both', direction='in', labelsize=font_size,
                        bottom=True, top=True, left=True, right=True)
        ax2.get_xaxis().set_ticks([])
        ax2.get_yaxis().set_ticklabels([])

    if disp_legend:
        ax.legend(loc=legend_loc, frameon=False, fontsize=font_size)

    # rms_threshold text
    if disp_thres_text:
        ymin, ymax = ax.get_ylim()
        yoff = (ymax - ymin) * 0.1
        if (rms_threshold - ymin) > 0.5 * (ymax - ymin):
            yoff *= -1.
        ax.annotate('Median Abs Dev * {}'.format(cutoff),
                    xy=(xmin + (xmax-xmin)*0.05, rms_threshold + yoff ),
                    color='k', xycoords='data', fontsize=font_size)
    return ax