예제 #1
0
def write_sp3(SP3_DF_in, outpath, skip_null_epoch=True, force_format_c=False):
    """
    Write DOCSTRING
    
    skip_null_epoch: Do not write an epoch if all sats are null (filtering)

    """
    ################## MAIN DATA
    LinesStk = []

    SP3_DF_wrk = SP3_DF_in.sort_values(["epoch", "sat"])

    EpochRawList = SP3_DF_wrk["epoch"].unique()
    SatList = sorted(SP3_DF_wrk["sat"].unique())
    SatList = list(reversed(SatList))
    SatListSet = set(SatList)
    EpochUsedList = []

    for epoc in EpochRawList:
        SP3epoc = pd.DataFrame(SP3_DF_wrk[SP3_DF_wrk["epoch"] == epoc])
        ## Missing Sat
        MissingSats = SatListSet.difference(set(SP3epoc["sat"]))

        for miss_sat in MissingSats:
            miss_line = SP3epoc.iloc[0].copy()
            miss_line["sat"] = miss_sat
            miss_line["const"] = miss_sat[0]
            miss_line["x"] = 0.000000
            miss_line["y"] = 0.000000
            miss_line["z"] = 0.000000
            miss_line["clk"] = 999999.999999

            SP3epoc = SP3epoc.append(miss_line)

        SP3epoc.sort_values("sat", inplace=True, ascending=False)
        timestamp = conv.dt2sp3_timestamp(conv.numpy_datetime2dt(epoc)) + "\n"

        linefmt = "P{:}{:14.6f}{:14.6f}{:14.6f}{:14.6f}\n"

        LinesStkEpoch = []
        sum_val_epoch = 0
        for ilin, lin in SP3epoc.iterrows():
            line_out = linefmt.format(lin["sat"], lin["x"], lin["y"], lin["z"],
                                      lin["clk"])

            sum_val_epoch += lin["x"] + lin["y"] + lin["z"]

            LinesStkEpoch.append(line_out)

        ### if skip_null_epoch activated, print only if valid epoch
        if not (np.isclose(sum_val_epoch, 0) and skip_null_epoch):
            LinesStk.append(timestamp)  # stack the timestamp
            LinesStk = LinesStk + LinesStkEpoch  # stack the values
            EpochUsedList.append(epoc)  # stack the epoc as dt

    ################## HEADER
    ######### SATELLITE LIST

    Satline_stk = []
    Sigmaline_stk = []

    if force_format_c:
        nlines = 5
    else:
        div, mod = np.divmod(len(SatList), 17)

        if div < 5:
            nlines = 5
        else:
            nlines = div

            if mod != 0:
                nlines += 1

    for i in range(nlines):
        SatLine = SatList[17 * i:17 * (i + 1)]
        SatLineSigma = len(SatLine) * " 01"

        if len(SatLine) < 17:
            complem = " 00" * (17 - len(SatLine))
        else:
            complem = ""

        if i == 0:
            nbsat4line = len(SatList)
        else:
            nbsat4line = ''

        satline = "+  {:3}   ".format(nbsat4line) + "".join(
            SatLine) + complem + "\n"
        sigmaline = "++         0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0\n"
        sigmaline = "++       " + SatLineSigma + complem + "\n"

        Satline_stk.append(satline)
        Sigmaline_stk.append(sigmaline)

    ######### 2 First LINES
    start_dt = conv.numpy_datetime2dt(np.min(EpochUsedList))

    header_line1 = "#cP" + conv.dt2sp3_timestamp(
        start_dt, False) + "     {:3}".format(
            len(EpochUsedList)) + "   u+U IGSXX FIT  XXX\n"

    delta_epoch = int(utils.most_common(np.diff(EpochUsedList) * 10**-9))
    MJD = conv.dt2MJD(start_dt)
    MJD_int = int(np.floor(MJD))
    MJD_dec = MJD - MJD_int
    gps_wwww, gps_sec = conv.dt2gpstime(start_dt, False, "gps")

    header_line2 = "## {:4} {:15.8f} {:14.8f} {:5} {:15.13f}\n".format(
        gps_wwww, gps_sec, delta_epoch, MJD_int, MJD_dec)

    ######### HEADER BOTTOM
    header_bottom = """%c M  cc GPS ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%f  1.2500000  1.025000000  0.00000000000  0.000000000000000
%f  0.0000000  0.000000000  0.00000000000  0.000000000000000
%i    0    0    0    0      0      0      0      0         0
%i    0    0    0    0      0      0      0      0         0
/* PCV:IGSXX_XXXX OL/AL:FESXXXX  NONE     YN CLK:CoN ORB:CoN
/*     GeodeZYX Toolbox Output
/*
/*
"""

    ################## FINAL STACK

    FinalLinesStk = []

    FinalLinesStk.append(header_line1)
    FinalLinesStk.append(header_line2)
    FinalLinesStk = FinalLinesStk + Satline_stk + Sigmaline_stk
    FinalLinesStk.append(header_bottom)
    FinalLinesStk = FinalLinesStk + LinesStk + ["EOF"]

    FinalStr = "".join(FinalLinesStk)

    F = open(outpath, "w+")
    F.write(FinalStr)
def write_sp3(SP3_DF_in,
              outpath,
              outname=None,
              prefix='orb',
              skip_null_epoch=True,
              force_format_c=False):
    """
    Write a SP3 file from an Orbit DataFrame

    Parameters
    ----------
    SP3_DF_in : DataFrame
        Input Orbit DataFrame.
    outpath : str
        The output path of the file (see also outname).
    outname : None or str, optional
        None = outpath is the full path (directory + filename) of the output.
        A string = a manual name for the file.
        'auto_old_cnv' = automatically generate the filename (old convention)
        'auto_new_cnv' = automatically generate the filename (new convention)
        The default is None.
    prefix : str, optional
        the output 3-char. name of the AC. The default is 'orb'.
    skip_null_epoch : bool, optional
        Do not write an epoch if all sats are null (filtering). 
        The default is True.
    force_format_c : bool, optional
        DESCRIPTION. The default is False.

    Returns
    -------
    The string containing the formatted SP3 data.
    """

    ################## MAIN DATA
    LinesStk = []

    SP3_DF_wrk = SP3_DF_in.sort_values(["epoch", "sat"])

    EpochRawList = SP3_DF_wrk["epoch"].unique()
    SatList = sorted(SP3_DF_wrk["sat"].unique())
    SatList = list(reversed(SatList))
    SatListSet = set(SatList)
    EpochUsedList = []

    if not "clk" in SP3_DF_wrk.columns:
        SP3_DF_wrk["clk"] = 999999.999999

    for epoc in EpochRawList:
        SP3epoc = pd.DataFrame(SP3_DF_wrk[SP3_DF_wrk["epoch"] == epoc])
        ## manage missing Sats for the current epoc
        MissingSats = SatListSet.difference(set(SP3epoc["sat"]))

        for miss_sat in MissingSats:
            miss_line = SP3epoc.iloc[0].copy()
            miss_line["sat"] = miss_sat
            miss_line["const"] = miss_sat[0]
            miss_line["x"] = 0.000000
            miss_line["y"] = 0.000000
            miss_line["z"] = 0.000000
            miss_line["clk"] = 999999.999999

            SP3epoc = SP3epoc.append(miss_line)
        #### end of missing sat bloc

        SP3epoc.sort_values("sat", inplace=True, ascending=False)
        timestamp = conv.dt2sp3_timestamp(conv.numpy_dt2dt(epoc)) + "\n"

        linefmt = "P{:}{:14.6f}{:14.6f}{:14.6f}{:14.6f}\n"

        LinesStkEpoch = []
        sum_val_epoch = 0
        for ilin, lin in SP3epoc.iterrows():
            if not "clk" in lin.index:  # manage case if no clk in columns
                lin["clk"] = 999999.999999
            line_out = linefmt.format(lin["sat"], lin["x"], lin["y"], lin["z"],
                                      lin["clk"])

            sum_val_epoch += lin["x"] + lin["y"] + lin["z"]

            LinesStkEpoch.append(line_out)

        ### if skip_null_epoch activated, print only if valid epoch
        if not (np.isclose(sum_val_epoch, 0) and skip_null_epoch):
            LinesStk.append(timestamp)  # stack the timestamp
            LinesStk = LinesStk + LinesStkEpoch  # stack the values
            EpochUsedList.append(epoc)  # stack the epoc as dt

    ################## HEADER
    ######### SATELLITE LIST

    Satline_stk = []
    Sigmaline_stk = []

    if force_format_c:
        nlines = 5
    else:
        div, mod = np.divmod(len(SatList), 17)

        if div < 5:
            nlines = 5
        else:
            nlines = div

            if mod != 0:
                nlines += 1

    for i in range(nlines):
        SatLine = SatList[17 * i:17 * (i + 1)]
        SatLineSigma = len(SatLine) * " 01"

        if len(SatLine) < 17:
            complem = " 00" * (17 - len(SatLine))
        else:
            complem = ""

        if i == 0:
            nbsat4line = len(SatList)
        else:
            nbsat4line = ''

        satline = "+  {:3}   ".format(nbsat4line) + "".join(
            SatLine) + complem + "\n"
        sigmaline = "++         0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0\n"
        sigmaline = "++       " + SatLineSigma + complem + "\n"

        Satline_stk.append(satline)
        Sigmaline_stk.append(sigmaline)

    ######### 2 First LINES
    start_dt = conv.numpy_dt2dt(np.min(EpochUsedList))

    header_line1 = "#cP" + conv.dt2sp3_timestamp(
        start_dt, False) + "     {:3}".format(
            len(EpochUsedList)) + "   u+U IGSXX FIT  XXX\n"

    delta_epoch = int(utils.most_common(np.diff(EpochUsedList) * 10**-9))
    MJD = conv.dt2MJD(start_dt)
    MJD_int = int(np.floor(MJD))
    MJD_dec = MJD - MJD_int
    gps_wwww, gps_sec = conv.dt2gpstime(start_dt, False, "gps")

    header_line2 = "## {:4} {:15.8f} {:14.8f} {:5} {:15.13f}\n".format(
        gps_wwww, gps_sec, delta_epoch, MJD_int, MJD_dec)

    ######### HEADER BOTTOM
    header_bottom = """%c M  cc GPS ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%f  1.2500000  1.025000000  0.00000000000  0.000000000000000
%f  0.0000000  0.000000000  0.00000000000  0.000000000000000
%i    0    0    0    0      0      0      0      0         0
%i    0    0    0    0      0      0      0      0         0
/* PCV:IGSXX_XXXX OL/AL:FESXXXX  NONE     YN CLK:CoN ORB:CoN
/*     GeodeZYX Toolbox Output
/*
/*
"""

    ################## FINAL STACK

    FinalLinesStk = []

    FinalLinesStk.append(header_line1)
    FinalLinesStk.append(header_line2)
    FinalLinesStk = FinalLinesStk + Satline_stk + Sigmaline_stk
    FinalLinesStk.append(header_bottom)
    FinalLinesStk = FinalLinesStk + LinesStk + ["EOF"]

    FinalStr = "".join(FinalLinesStk)

    ### Manage the file path
    prefix_opera = prefix

    if not outname:
        outpath_opera = outpath
    elif outname == 'auto_old_cnv':
        week, dow = conv.dt2gpstime(start_dt)
        filename = prefix_opera + str(week) + str(dow) + '.sp3'
        outpath_opera = os.path.join(outpath, filename)

    elif outname == 'auto_new_cnv':
        print("ERR: not implemented yet !!!!!")
        raise Exception

    F = open(outpath_opera, "w+")
    F.write(FinalStr)