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)
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)
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() })
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)
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)
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":