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)