Ejemplo n.º 1
0
def read_eop_C04(file_path_in):
    """
    read EOP C04 file

    Parameters
    ----------
    file_path_in : str
        path of the EOP C04 file.

    Returns
    -------
    DF : DataFrame
        out DataFrame.

    """
    DF = pd.read_csv(file_path_in,
                     delim_whitespace=True,
                     skip_blank_lines=True,
                     skiprows=13,
                     header=None)

    cols = [
        'yyyy', 'mm', 'dd', 'MJD', 'x', 'y', 'UT1-UTC', 'LOD', 'dX', 'dY',
        'x_Err', 'y_Err', 'UT1-UTC_Err', 'LOD_Err', 'dX_Err', 'dY_Err'
    ]

    DF.columns = cols

    DF["epoch"] = conv.MJD2dt(DF.MJD)

    return DF
def stations_in_EPOS_sta_coords_file_mono(coords_file_path):
    """
    Gives stations in a EPOS coords. file (YYYY_DDD_sta_coordinates)

    Parameters
    ----------
    coords_file_path : str
        path of the EPOS coords. file.

    Returns
    -------
    epoch : datetime
        the main mean epoch in the EPOS coords. file.
    stats_list : list
        list of 4 char station list.
    """

    SITE_line_list = utils.grep(coords_file_path, " SITE            m")

    stats_list = []
    mean_mjd_list = []
    for l in SITE_line_list:
        stat = l.split()[8].lower()
        stats_list.append(stat)
        mean_mjd = np.mean([float(l.split()[6]), float(l.split()[7])])
        mean_mjd_list.append(mean_mjd)

    mjd_final = utils.most_common(mean_mjd_list)
    epoch = conv.MJD2dt(mjd_final)
    return epoch, stats_list
def read_combi_sum_full(sum_full_file,
                        RMS_lines_output=True,
                        set_PRN_as_index=True):
    Vals_stk = []

    for l in open(sum_full_file):

        F = l.split()
        if "|" in F:
            F.remove("|")

        ### Find date line
        if "MJD:" in l:
            date_line = l

        ### Skip useless lines
        if not "|" in l or "------" in l:
            continue

        ### Find AC list
        if "PRN" in l:
            ACs_list = F
            ACs_list.append("RMS_sat")
            ACs_list.append("PRN_str")
            ACs_list.append("CONST")

        elif F[0].isnumeric():
            Fout = [float(f) for f in F]
            Fout[0] = int(Fout[0])
            #Add the PRN string and the constellation
            Fout.append(prn_int_2_prn_str(int(Fout[0])))
            Fout.append(Fout[-1][0])

            Vals_stk.append(Fout)

        elif "RMS" in F[0] and RMS_lines_output:
            Fout = [float(f) for f in F[1:]]
            Fout.append(np.nan)
            Fout.insert(0, F[0])
            #Add FAKE the PRN string and the constellation
            Fout.append(F[0])
            Fout.append(None)

            Vals_stk.append(Fout)

    DF = pd.DataFrame(Vals_stk, columns=ACs_list)

    ### Date management
    mjd = float(date_line.split("MJD:")[1].split()[0])
    date_dt = conv.MJD2dt(mjd)

    DF.date_mjd = mjd
    DF.date_dt = date_dt

    DF.date_gps = utils.join_improved("", conv.dt2gpstime(date_dt))

    if set_PRN_as_index:
        DF.set_index("PRN_str", inplace=True)

    return DF
Ejemplo n.º 4
0
def read_gfz_trop(trpfile):
    """
    This function is reading GFZ troposphere sinex into Pandas DataFrame

    Parameters
    ----------
    trpfile : Str
        File name of GFZ troposphere sinex.

    Returns
    -------
    DF : Pandas DataFrame
        Pandas Dataframe of GFZ troposphere sinex.

    """
    fields = []
    flagtrop = False

    for line in open(trpfile,"r",encoding = "ISO-8859-1"):
        if re.compile('TROP/SOLUTION').search(line):
            flagtrop = not flagtrop
            continue

        if flagtrop ==True and line[0] == ' ':
            field = line.split()
            fields.append(field)
        else:
            continue

    DF = pd.DataFrame(fields)
    DF.drop(columns=[0,8,9,10,11,12,18,19,20],inplace=True)
    DF.columns = ['STAT','epoc','year','doy','secofday','ztd_est','ztd_est_std','num_sat','tgn_est','tgn_est_std','tge_est','tge_est_std']
    cols_numeric = ['epoc','ztd_est','ztd_est_std','num_sat','tgn_est','tgn_est_std','tge_est','tge_est_std']
    DF[cols_numeric] = DF[cols_numeric].apply(pd.to_numeric, errors='coerce')
    DF['epoc'] = conv.MJD2dt(DF['epoc'].values)
    DF['epoc'] = DF['epoc'].dt.floor('H')
    return DF
def ESMGFZ_extrapolator(path_or_netcdf_object_in,
                        time_xtrp,
                        lat_xtrp,
                        lon_xtrp,
                        wished_values=("duV","duNS","duEW"),
                        output_type = "DataFrame",
                        debug=False,verbose=True,
                        time_smart=True,
                        interp_method="splinef2d"):
    """
    Extrapolate loading values from the EMSGFZ models
    esmdata.gfz-potsdam.de:8080/

    Parameters
    ----------
    path_or_netcdf_object_in : string, list of strings or NetCDF object
        Input 
        can be a file path (string), a list of string (will be concatenated)
        or direcly the NetCDF object (faster).
    time_xtrp : float or float iterable
        time for the wished extrapolated values
        for daily files: hours of day [0..23].
        for yearly files: day of years [0..364].
    lat_xtrp : float or float iterable
        latitude component for the wished extrapolated values
        ranging from [-90..90]
    lon_xtrp : float or float iterable
        longitude component for the wished extrapolated values.
        ranging from [-180..180]
    wished_values : tuple of string, optional
        the components of the extrapolated values. 
        The default is ("duV","duNS","duEW").
    output_type : str, optional
        Choose the output type.
        "DataFrame","dict","array","tuple","list"
        The default is "DataFrame".
    debug : bool, optional
        returns the NetCDF object for debug purposes

    Returns
    -------
    Points_out : see output_type
        The extrapolated values.

    """
    
    if not utils.is_iterable(time_xtrp):
        time_xtrp = [time_xtrp]
    if not utils.is_iterable(lat_xtrp):
        lat_xtrp = [lat_xtrp]
    if not utils.is_iterable(lon_xtrp):
        lon_xtrp = [lon_xtrp]
    
    Points_xtrp = (time_xtrp,lat_xtrp,lon_xtrp)

    if type(path_or_netcdf_object_in) is str:
        NC =  nc.Dataset(path_or_netcdf_object_in)
    elif type(path_or_netcdf_object_in) in (nc.Dataset,nc.MFDataset):
        NC = path_or_netcdf_object_in
    else:
        NC = nc.MFDataset(sorted(path_or_netcdf_object_in))
        
    if debug:
        return NC
    
    time_orig = np.array(NC['time'][:])
    
    if time_smart:
        # we work in MJD
        start_date = conv.dt2MJD(conv.str_date2dt(NC['time'].units[11:]))
        if len(time_orig) <= 366:
            time = start_date - .0 + time_orig 
        else:
            time = start_date - .0 + np.array(range(len(time_orig)))
        
    lat  = np.flip(np.array(NC['lat'][:]))  ### we flip the lat because not ascending !
    lon  = np.array(NC['lon'][:])
    
    Points = (time,lat,lon)    
    
    WishVals_Stk = []
    WishVals_dic = dict()
    
    #### prepare dedicated time, lat, lon columns
    Points_xtrp_array = np.array(list(itertools.product(*Points_xtrp)))
    WishVals_dic['time'] = Points_xtrp_array[:,0]
    WishVals_dic['lat']  = Points_xtrp_array[:,1]
    WishVals_dic['lon']  = Points_xtrp_array[:,2]
    
    
    ### do the interpolation for the wished value
    for wishval in wished_values:
        if verbose:
            print("INFO:",wishval,"start interpolation at",dt.datetime.now())
        
        #### Val = np.array(NC[wishval]) ### Slow
        Val = NC[wishval][:]
        
        if verbose:
            print("INFO:",wishval,"grid loaded at",dt.datetime.now())
            
        Val = np.flip(Val,1) ### we flip the lat because not ascending !
        Val_xtrp = scipy.interpolate.interpn(Points,Val,
                                             Points_xtrp,
                                             method=interp_method)
        WishVals_Stk.append(Val_xtrp)
        WishVals_dic[wishval] = Val_xtrp
    
    #### choose the output
    if output_type == "DataFrame":
        Points_out = pd.DataFrame(WishVals_dic)
        if time_smart:
            Points_out['time_dt'] = conv.MJD2dt(Points_out['time'])
    elif output_type == "dict":
        Points_out = WishVals_dic
    elif output_type == "array":
        Points_out = np.column_stack(WishVals_Stk)
    elif output_type == "tuple":
        Points_out = tuple(WishVals_Stk)
    elif output_type == "list":
        Points_out = list(WishVals_Stk)
    else:
        Points_out = WishVals_Stk
        
    return Points_out
    
def timeline_plotter(datadico,start = dt.datetime(1980,1,1) ,
                     end = dt.datetime(2099,1,1),dots_plot=False,
                     jul_date_plot=False,datadico_anex_list = [],
                     use_only_stats_of_main_datadico=False,
                     colordico_for_main_datadico=None):
    """
    A simpler version has been commited to geodezyx toolbox for archive
    on 20180118 15:59A
    """

    fig , ax = plt.subplots()
    ax.xaxis.grid(True)
    ax.yaxis.grid(True)

    if not use_only_stats_of_main_datadico:
        stats_concat_list = list(datadico.keys()) + sum([list(e.keys()) for e in datadico_anex_list], [])
        stats_concat_list = list(reversed(sorted(list(set(stats_concat_list)))))
    else:
        stats_concat_list = list(reversed(sorted(list(datadico.keys()))))

    # the plot has not the same behavior if it is the morning or not 
    # (rinexs timelines wont be ploted if it is the morning)
    if dt.datetime.now().hour < 12:
        morning_shift = dt.timedelta(days=1)
    else:
        morning_shift = dt.timedelta(days=0)

    legend_list = [] # must be here before the loop
    for i,stat in enumerate(stats_concat_list):
        # PART 1 : PLOT MAIN DATADICO
        if not stat in datadico.keys():
            continue

        #T = Time, O = Station name (Observation)
        Torig = [ e[-1] for e in datadico[stat] ]
        Oorig = [ e[1]  for e in datadico[stat] ]

        # Time windowing
        T , O = [] , []
        for t , o in zip(Torig , Oorig):
            if ( start - morning_shift ) <= t <= end: 
                T.append(t)
                O.append(o)

        T,O = utils.sort_binom_list(T,O)

        TMJD=conv.dt2MJD(T)
        TGrpAll = utils.consecutive_groupIt(TMJD,True) # Tuples (start,end) of continue period

        for tgrp in TGrpAll:
            color1 = 'C0'
            color2 = ''
            extra_archive = False

            ###*** managing colors
            if colordico_for_main_datadico:
                igrpstart    = TMJD.index(tgrp[0])
                igrpend      = TMJD.index(tgrp[1])
                Ogrp         = O[igrpstart:igrpend+1]
                Tgrp         = TMJD[igrpstart:igrpend+1] # all dates in the current continue period

                opt_set      = list(set(Ogrp))

                if len(opt_set) == 1: # Regular case : only one archive
                    if opt_set[0] in colordico_for_main_datadico:
                        color1 = colordico_for_main_datadico[opt_set[0]]
                else: # several archives ... so the line has to be splited in segments
                    extra_archive = True
                    OSubgrp = utils.identical_groupIt(Ogrp)
                    TSubgrp = utils.sublistsIt(Tgrp , [len(e) for e in OSubgrp])

                    Tgrp_plt      = [ (e[0] , e[-1] + 1)    for e in TSubgrp ] # +1 because the end boundary day is not included
                    Ogrp_plt      = [ list(set(e))[0] for e in OSubgrp     ]
                    Color_grp_plt = [ colordico_for_main_datadico[e] if e in colordico_for_main_datadico else color2 for e in Ogrp_plt ]
            ###*** End of managing colors

            tgrp = (tgrp[0] , tgrp[1] + 1) # +1 because the end boundary day is not included
                                           # must stay there, in case of not colordico_for_main_datadico

            if not jul_date_plot:
                tgrp = conv.MJD2dt(tgrp)
                if extra_archive:
                    Tgrp_plt = [ (conv.MJD2dt(e[0]) , conv.MJD2dt(e[1])) for e in Tgrp_plt ]

            #PLOT part
            if tgrp[0] == tgrp[1] + dt.timedelta(days=1): # CASE NO PERIOD, ONLY ONE DAY
                ax.plot(tgrp[0],i , '.' + color1)
            else:                  # CASE PERIOD
                if not extra_archive: # ONE ARCHIVE REGULAR CASE
                    ax.plot(tgrp,[i]*2, '-' + color1)
                else:              # SUBCASE "EXTRA" : SEVERAL ARCHIVE
                    for tt , cc in zip(Tgrp_plt , Color_grp_plt):
                        ax.plot(tt,[i]*2 , '-' + cc)

        # PART 2 : PLOT ANEX DATADICO
        for idatadico_anex,datadico_anex in enumerate(datadico_anex_list):
            if stat in list(datadico_anex.keys()):
                T = datadico_anex[stat]
                T = [ t for t in T if start <= t <= end  ]
                T = sorted(T)

                if jul_date_plot:
                    T = conv.MJD2dt(T)

                pale_blue_dot , = ax.plot(T,i*np.ones(len(T)), 'o', color='skyblue',label="final SNX")
                legend_list     = [pale_blue_dot]

    #### LEGEND
    if colordico_for_main_datadico:
        import matplotlib.lines as mlines
        for arcnam , col in colordico_for_main_datadico.items():
            legend_list.append(mlines.Line2D([], [], color=col,
                                                     label=arcnam))
            plt.legend(handles=legend_list,loc='upper left',ncol=3,
                       columnspacing=1)


#    ax.set_yticks(np.arange(0,len(plotstat_lis)-1),plotstat_lis)
    plt.yticks(np.arange(0,len(stats_concat_list)),stats_concat_list)
    fig.autofmt_xdate()
    koef = np.sqrt(2) * 1
    fig.set_size_inches(koef*11.69,koef*len(stats_concat_list) * 0.28) #16.53
    ax.set_ylim([-1 , len(stats_concat_list) + 1])

    return fig
Ejemplo n.º 7
0
def read_eop_finals(file_path_in,
                    precnut_model=2000,
                    simplified_EOP_DF="mixed"):
    """
    read EOP finals file


    Parameters
    ----------
    file_path_in : str
        path of the EOP finals file.
    precnut_model : int, optional
        IAU Precession-Nutation Model. Valid values are 1980 and 2000.
        The default is 2000.

    Returns
    -------
    DF : DataFrame
        out DataFrame - Complete content of the finals file.
    DF2 : DataFrame
        out DataFrame - Simplified content of the finals file.
        Based on C04 EOP DataFrame structure.
        If no Bulletin-B values provided, use Bulletin-A.
        
    Note
    ----
    Format description
    https://github.com/marando/phpIERS/blob/master/src/Marando/IERS/default/readme.finals
    """

    if precnut_model == 2000:
        x_or_psi = "X"
        y_or_eps = "Y"
    elif precnut_model == 1980:
        x_or_psi = "PSI"
        y_or_eps = "EPS"
    else:
        raise Exception

    cols = ((0, 2), (2, 4), (4, 6), (6, 7), (7, 15), (15, 16), (16, 17),
            (17, 18), (18, 27), (27, 36), (36, 37), (37, 46), (46, 55),
            (55, 57), (57, 58), (58, 68), (68, 78), (78, 79), (79, 86),
            (86, 93), (93, 95), (95, 96), (96, 97), (97, 106), (106, 115),
            (115, 116), (116, 125), (125, 134), (134, 144), (144, 154),
            (154, 165), (165, 175), (175, 185))

    col_names = [
        'yyyy', 'mm', 'dd', '[blank]', 'MJD', '[blank]', 'flg_xy', '[blank]',
        'x_A', 'x_A_Err', '[blank]', 'y_A', 'y_A_Err', '[blanks]',
        'flg_UT1-UTC', 'UT1-UTC_A', 'UT1-UTC_A_Err', '[blank]', 'LOD_A',
        'LOD_A_Err', '[blanks]', 'flg_nut', '[blank]', 'd' + x_or_psi + '_A',
        'd' + x_or_psi + '_A_Err', '[blank]', 'd' + y_or_eps + '_A',
        'd' + y_or_eps + '_A_Err', 'x_B', 'y_B', 'UT1-UTC_B',
        'd' + x_or_psi + '_B', 'd' + y_or_eps + '_B'
    ]

    DF = pd.read_fwf(file_path_in, colspecs=cols, header=None)
    DF.columns = col_names
    ### remove everything with NaN
    DF.dropna(axis=1, how="all", inplace=True)
    ### if not x_A provided, then its a blank line
    DF = DF[np.logical_not(np.isnan(DF['x_A']))]

    ### set mjd as int
    DF["MJD"] = DF["MJD"].astype(np.int64)

    #### DF 2 is a simplified version, base on the C04 DF
    DF2 = pd.DataFrame()
    DF2["epoch"] = conv.MJD2dt(DF["MJD"])

    if simplified_EOP_DF == 'mixed':
        ### Create epoch and use B-values per default
        DF2[['MJD', 'x', 'y', 'UT1-UTC', 'LOD', 'dX', 'dY']] = DF[[
            'MJD', 'x_B', 'y_B', 'UT1-UTC_B', 'LOD_A', 'dX_B', 'dY_B'
        ]]

        DF2["Bul"] = "B"
        ### If no B-values, use A-values
        DF2.loc[np.isnan(DF.x_B), 'Bul'] = "A"
        DF2.loc[np.isnan(DF.x_B), 'x'] = DF.loc[np.isnan(DF.x_B), 'x_A']
        DF2.loc[np.isnan(DF.y_B), 'y'] = DF.loc[np.isnan(DF.y_B), 'y_A']
        DF2.loc[np.isnan(DF['UT1-UTC_B']),
                'UT1-UTC'] = DF.loc[np.isnan(DF['UT1-UTC_B']), 'UT1-UTC_A']
        DF2.loc[np.isnan(DF.dX_B), 'dX'] = DF.loc[np.isnan(DF.dX_B), 'dX_A']
        DF2.loc[np.isnan(DF.dX_B), 'dY'] = DF.loc[np.isnan(DF.dY_B), 'dY_A']

    elif simplified_EOP_DF == "A":
        DF2[['MJD', 'x', 'y', 'UT1-UTC', 'LOD', 'dX', 'dY']] = DF[[
            'MJD', 'x_A', 'y_A', 'UT1-UTC_A', 'LOD_A', 'dX_A', 'dY_A'
        ]]
        DF2["Bul"] = "A"
        DF2.dropna(axis=1, how="all", inplace=True)

    elif simplified_EOP_DF == "B":
        DF2[['MJD', 'x', 'y', 'UT1-UTC', 'LOD', 'dX', 'dY']] = DF[[
            'MJD', 'x_B', 'y_B', 'UT1-UTC_B', 'LOD_A', 'dX_B', 'dY_B'
        ]]
        DF2["Bul"] = "B"
        DF2.dropna(axis=1, how="all", inplace=True)

    else:
        print("ERR: read_eop_C04: check the  simplified_EOP_DF parameter !!!")
        raise Exception

    return DF, DF2
Ejemplo n.º 8
0
def read_sp3_header(sp3_in, ac_name_in=None):
    """
    Read a SP3 file header and return a Pandas DataFrame
    with sat. PRNs and sigmas contained in the header

    Parameters
    ----------
    sp3_in : str or list
        path of the SP3 file
        can handle gzip-compressed file (with .gz/.GZ extension) 

        can also handle the sp3 content as a list of strings
        (useful when read_sp3_header is used as a subfunction of read_sp3)
        
    ac_name_in : str
        force the AC name
        (necessary when read_sp3_header is used as a subfunction of read_sp3)
        
    Returns
    -------
    Header_DF : Pandas DataFrame
        2 columns "sat", "sigma"

    Note
    -------
    More infos about the sigma
    http://acc.igs.org/orbacc.txt
    """

    if type(sp3_in) is list:
        ### case when read_sp3_header is used as a subfunction of read_sp3
        Lines = sp3_in
    elif sp3_in[-2:] in ("gz", "GZ"):
        F = gzip.open(sp3_in, "r+")
        Lines = [e.decode('utf-8') for e in F]
    else:
        F = open(sp3_in, 'r+')
        Lines = F.readlines()

    if not ac_name_in:
        ac_name = os.path.basename(sp3_in)[:3]
    else:
        ac_name = ac_name_in

    Sat_prn_list = []
    Sat_sig_list = []

    for il, l in enumerate(Lines):
        if il == 1:
            date = conv.MJD2dt(int(l.split()[4]))
        if l[:2] == "+ ":
            Sat_prn_list.append(l)
        if l[:2] == "++":
            Sat_sig_list.append(l)
        if l[0] == "*":
            break

    ### PRN part
    Sat_prn_list_clean = []
    for prn_line in Sat_prn_list:
        prn_line_splited = prn_line.split()
        prn_line_splited = [e for e in prn_line_splited if not "+" in e]
        prn_line_splited = [e for e in prn_line_splited if not e == "0"]
        Sat_prn_list_clean = Sat_prn_list_clean + prn_line_splited
    try:
        sat_nbr = int(Sat_prn_list_clean[0])
    except:
        sat_nbr = 0

    Sat_prn_list_clean = Sat_prn_list_clean[1:]

    Sat_prn_string = "".join(Sat_prn_list_clean)

    Sat_prn_list_final = []
    for i in range(sat_nbr):
        Sat_prn_list_final.append(Sat_prn_string[i * 3:i * 3 + 3])

    ### Sigma part
    Sat_sig_list_clean = []
    for sig_line in Sat_sig_list:
        sig_line_splited = sig_line.split()
        sig_line_splited = [e for e in sig_line_splited if not "+" in e]
        Sat_sig_list_clean = Sat_sig_list_clean + sig_line_splited

    Sat_sig_list_final = [int(e) for e in Sat_sig_list_clean[:sat_nbr]]

    ### Export part
    AC_name_list = [ac_name] * sat_nbr
    Date_list = [date] * sat_nbr

    Header_DF = pd.DataFrame(list(
        zip(AC_name_list, Sat_prn_list_final, Sat_sig_list_final, Date_list)),
                             columns=["AC", "sat", "sigma", "epoch"])

    return Header_DF