Пример #1
0
    def get_fields(self, write_level=None):
        """List names of fields in table with write level at or above `write_level`

        Args:
            write_level (String):  Lowest write level allowed for fields.

        Returns:
            List:  Strings with names of fields.
        """
        if write_level is None:
            level = min(enums.get_enum("write_level"))
        else:
            level = enums.get_value("write_level", write_level)

        return sorted(f for f, wl in self._write_levels.items() if wl >= level)
Пример #2
0
def sisre_report(dset):
    """Write SISRE report

    Args:
        dset (Dataset):       A dataset containing the data.
    """
    write_level = config.tech.get("write_level",
                                  default="operational").as_enum("write_level")

    # TODO: Better solution?
    if "sampling_rate" not in dset.vars:  # necessary if called for example by where_concatenate.py
        dset.vars["sampling_rate"] = ""

    with files.open(file_key="output_sisre_report",
                    file_vars=dset.vars,
                    mode="wt") as fid:
        _write_title(fid, dset.rundate)
        _write_information(fid)
        _write_config(fid)
        fid.write("\n# Satellite status\n\n")
        # _unhealthy_satellites(fid, dset)
        # _eclipse_satellites(fid, dset)

        # Generate figure directory to save figures generated for SISRE report
        fid.write("\n# SISRE analysis results\n\n")
        figure_dir = files.path("output_sisre_report_figure",
                                file_vars=dset.vars)
        figure_dir.mkdir(parents=True, exist_ok=True)

        _plot_scatter_orbit_and_clock_differences(fid, figure_dir, dset)
        _plot_scatter_sisre(fid, figure_dir, dset)
        _plot_scatter_field(fid, figure_dir, dset, "sisre")
        # _plot_scatter_field(fid, figure_dir, dset, 'sisre', label=False, legend=False)
        _plot_histogram_sisre(fid, figure_dir, dset)
        _satellite_statistics_and_plot(fid, figure_dir, dset)

        fid.write("\n# Analysis of input files\n\n")
        if write_level <= enums.get_value("write_level", "detail"):
            # _plot_scatter_satellite_bias(fid, figure_dir, dset)
            _plot_scatter_field(fid, figure_dir, dset, "bias_brdc")
            _plot_scatter_field(fid, figure_dir, dset, "bias_precise")

    # Generate PDF from Markdown file
    _markdown_to_pdf(dset)
Пример #3
0
    def read(self, json_data, hdf5_data):
        """Read a data table from file

        This method is called from Dataset.read.

        This method is responsible for recovering its data from the json_data and hdf5_data structures, that were
        written by write(). Just like add(), read needs to register all fields in its self._fields dictionary so that
        the fields can be calles as attributes on the Table-object.

        Args:
            json_data:  Dict, data read from JSON-file.
            hdf5_data:  HDF5 dataset, data read from HDF5-file.
        """
        self._units.update(
            json_data.get("_units", dict()).get(self.name, dict()))
        write_levels = json_data.get("_write_levels",
                                     dict()).get(self.name, dict())
        self._write_levels.update({
            f: enums.get_value("write_level", wl)
            for f, wl in write_levels.items()
        })
Пример #4
0
    def add(self, fieldname, write_level=None, **_kwargs):
        """Add a field to a data table

        This method will be called once for each field added to this table from a dataset (using the
        add_datatype-method). See Dataset._add for details.

        The implementation of this method is responsible for adding the field to self._data and self._fields. It is
        also possible to add extra fields that typically will be calculated from the given field. These extra fields
        should be added to the self._fields-list as <fieldname>.<extra_field> (see PositionTable for an example of
        this).

        Note that the docstring of this function is copied to the corresponding add_datatype-method so args should
        include fieldnames (plural) and table as below, as well as any other arguments explicitly defined by the
        add-method. The docstring does not need to define a return value as that is eaten up by the
        add_datatype-method.

        Args:
            fieldnames:  String or list of strings with names of fields to be added.
            table:       String, name of table where fields are added (optional).
        """
        write_level = max(enums.get_enum(
            "write_level")).name if write_level is None else write_level
        self._write_levels[fieldname] = enums.get_value(
            "write_level", write_level)
Пример #5
0
def sisre_writer(dset):
    """Write SISRE analysis results

    Args:
        dset:       Dataset, a dataset containing the data.
    """
    write_level = config.tech.get("write_level", default="operational").as_enum("write_level")

    fields = (
        WriterField("time_date", (), object, "%21s", 19, "EPOCH"),
        WriterField("time", ("gps", "mjd"), float, "%14.6f", 14, "", "mjd"),
        WriterField("time_gpsweek", (), object, "%15s", 15, ""),
        WriterField("satellite", (), object, "%5s", 5, "SAT"),
        WriterField("used_iode", (), float, "%6d", 6, "IODE"),
        WriterField("trans_time_gpsweek", (), object, "%15s", 15, "TRANS_TIME"),
        WriterField("toe_gpsweek", (), object, "%15s", 15, "TOE"),
        WriterField("diff_trans_toe", (), float, "%8d", 8, "TM-TOE"),
        WriterField("diff_time_toe", (), float, "%8d", 8, "T-TOE"),
        WriterField("clk_diff", (), float, "%16.4f", 16, "ΔCLOCK"),
        WriterField("clk_diff_with_dt_mean", (), float, "%16.4f", 16, "ΔCLOCK_MEAN"),
        WriterField("dalong_track", (), float, "%16.4f", 16, "ΔALONG_TRACK"),
        WriterField("dcross_track", (), float, "%16.4f", 16, "ΔCROSS_TRACK"),
        WriterField("dradial", (), float, "%16.4f", 16, "ΔRADIAL"),
        WriterField("orb_diff_3d", (), float, "%16.4f", 16, "ORB_DIFF_3D"),
        WriterField("sisre_orb", (), float, "%16.4f", 16, "SISRE_ORB"),
        WriterField("sisre", (), float, "%16.4f", 16, "SISRE"),
    )

    # Add additional fields used by the writer
    dset.add_text(
        "time_date", val=[d.strftime("%Y/%m/%d %H:%M:%S") for d in dset.time.datetime], unit="YYYY/MM/DD hh:mm:ss"
    )
    dset.add_text(
        "time_gpsweek",
        val=[f"{t.gpsweek:04.0f}{t.gpsday:1.0f}:{t.gpssec:06.0f}" for t in dset.time],
        unit="wwwwd:ssssss",
    )
    dset.add_text(
        "trans_time_gpsweek",
        val=[f"{t.gpsweek:04.0f}{t.gpsday:1.0f}:{t.gpssec:06.0f}" for t in dset.used_transmission_time],
        unit="wwwwd:ssssss",
    )
    dset.add_text(
        "toe_gpsweek",
        val=[f"{t.gpsweek:04.0f}{t.gpsday:1.0f}:{t.gpssec:06.0f}" for t in dset.used_toe],
        unit="wwwwd:ssssss",
    )
    dset.add_float(
        "diff_trans_toe", val=(dset.used_transmission_time.mjd - dset.used_toe.mjd) * unit.day2second, unit="second"
    )
    dset.add_float("diff_time_toe", val=(dset.time.mjd - dset.used_toe.mjd) * unit.day2second, unit="second")
    dset.add_float("dalong_track", val=dset.orb_diff_acr.itrs[:, 0], unit=dset.unit("orb_diff_acr.itrs"))
    dset.add_float("dcross_track", val=dset.orb_diff_acr.itrs[:, 1], unit=dset.unit("orb_diff_acr.itrs"))
    dset.add_float("dradial", val=dset.orb_diff_acr.itrs[:, 2], unit=dset.unit("orb_diff_acr.itrs"))

    # Add 'detail' fields used by the writer
    if write_level <= enums.get_value("write_level", "detail"):
        fields += (
            WriterField("clk_brdc_com", (), float, "%16.4f", 16, "CLK_BRDC"),
            WriterField("clk_precise_com", (), float, "%16.4f", 16, "CLK_PRECISE"),
            WriterField("bias_brdc", (), float, "%10.4f", 10, "B_BRDC"),
            WriterField("bias_precise", (), float, "%10.4f", 10, "B_PREC"),
            WriterField("clk_sys", (), float, "%10.4f", 10, "CLK_SYS"),
        )

        dset.add_float("clk_sys", val=dset.clk_diff - dset.clk_diff_with_dt_mean, unit="meter")

    # List epochs ordered by satellites
    idx = np.concatenate([np.where(dset.filter(satellite=s))[0] for s in dset.unique("satellite")])

    # Put together fields in an array as specified by the fields-tuple
    output_list = list(zip(*(_get_field(dset, f.field, f.attrs) for f in fields)))
    output_array = np.array(output_list, dtype=[(f.field, f.dtype) for f in fields])[idx]

    # Write to disk
    # NOTE: np.savetxt is used instead of having a loop over all observation epochs, because the performance is better.
    file_path = files.path(f"output_sisre_{dset.dataset_id}", file_vars=dset.vars)
    header = [
        _get_header(dset),
        "".join(f"{f.header:>{f.width}s}" for f in fields),
        "".join(f"{f.unit if f.unit else dset.unit(f.field):>{f.width}s}" for f in fields),
        "_" * sum([f.width for f in fields]),
    ]
    np.savetxt(
        file_path,
        output_array,
        fmt=tuple(f.format for f in fields),
        header="\n".join(header),
        delimiter="",
        encoding="utf8",
    )

    # Append SISRE output path to SISRE output buffer file
    if config.tech.sisre_writer.write_buffer_file.bool:
        sisre_output_buffer.sisre_output_buffer(dset)
Пример #6
0
        ydata (numpy.ndarray):  Y-axis data
    """

AxhlineConfig = namedtuple("AxhlineConfig", ["type", "y_value", "color"])
AxhlineConfig.__doc__ = """A convenience class for defining matplotlib axhline configuration

    Args:
        type (str):             Type (e.g. GNSS identifier E or G for Galileo or GPS)
        y_value (float):        Y-value for horizontal line to be plotted in [m]
        color (str):            Color of horizontal line
    """

# Define dictionary with fields to be printed in SISRE report
write_level = config.tech.get("write_level",
                              default="operational").as_enum("write_level")
if write_level <= enums.get_value("write_level", "detail"):
    FIELDS = {
        "age_of_ephemeris": "Age of ephemeris",
        "sisre": "SISRE",
        "sisre_orb": "orbit-only SISRE",
        "orb_diff_3d": "3D orbit error",
        "clk_diff_with_dt_mean":
        "satellite clock correction difference $\Delta t$",
        "bias_brdc": "satellite bias of broadcast clocks",
        "bias_precise": "satellite bias of precise clocks",
    }
else:
    FIELDS = {
        "age_of_ephemeris":
        "Age of ephemeris",
        "sisre":