Module redvox.common.station_model
Prototype functions for station location and timing summary Provides an example of how to access the information from a Station object This module will contain methods to summarize a single Station
Expand source code
"""
Prototype functions for station location and timing summary
Provides an example of how to access the information from a Station object
This module will contain methods to summarize a single Station
"""
from typing import List, Optional
import math
from dataclasses import dataclass
from dataclasses_json import dataclass_json
import numpy as np
from redvox.common.station import Station
from redvox.api1000.wrapped_redvox_packet.sensors.location import LocationProvider
LOCATION_PROVIDER_IDX: int = 10
LATITUDE_IDX: int = 1
LONGITUDE_IDX: int = 2
ALTITUDE_IDX: int = 3
@dataclass_json
@dataclass
class LocationSummary:
"""
Summary of a Location. Includes the location sensor's name, source of data (provider), number of points,
and the mean and standard deviation of latitude, longitude, and altitude.
"""
name: str
provider: str
latitude_mean: float
latitude_standard_deviation: float
longitude_mean: float
longitude_standard_deviation: float
altitude_mean: Optional[float]
altitude_standard_deviation: float
num_pts: int
@staticmethod
def from_station(stn: Station) -> Optional[List["LocationSummary"]]:
"""
:param stn: Station to get data from
:return: List of LocationSummary grouped by provider or None
"""
loc = stn.find_loc_for_stats()
if loc:
samples: np.ndarray = loc.samples()
if loc.num_samples() == 1:
return [
LocationSummary(
loc.name,
LocationProvider(int(samples[LOCATION_PROVIDER_IDX][0])).name,
samples[LATITUDE_IDX][0],
0.0,
samples[LONGITUDE_IDX][0],
0.0,
samples[ALTITUDE_IDX][0],
0.0,
1,
)
]
# for each provider, create a new entry in the dictionary or append new data
loc_prov_to_data: dict = {}
lat_samples: np.ndarray = samples[LATITUDE_IDX]
lng_samples: np.ndarray = samples[LONGITUDE_IDX]
for j in range(min(len(lat_samples), len(lng_samples))):
if (not math.isnan(lat_samples[j])) and (not math.isnan(lng_samples[j])):
prov = LocationProvider(int(samples[LOCATION_PROVIDER_IDX][j])).name
data = np.array(
[
[samples[LATITUDE_IDX][j]],
[samples[LONGITUDE_IDX][j]],
[samples[ALTITUDE_IDX][j]],
]
)
loc_prov_to_data[prov] = (
data
if prov not in loc_prov_to_data.keys()
else np.concatenate([loc_prov_to_data[prov], data], 1)
)
loc_sums = []
for provider, loc_data in loc_prov_to_data.items():
loc_sums.append(
LocationSummary(
loc.name,
provider,
loc_data[0].mean(),
loc_data[0].std(),
loc_data[1].mean(),
loc_data[1].std(),
loc_data[2].mean(),
loc_data[2].std(),
len(loc_data[0]),
)
)
return loc_sums
return None
def example_of_print_loc_and_timing_summary(stn: Station):
"""
An example function that show how you can access location, GNSS, and time sync information and prints it
:param stn: Station to get data from
"""
print(f"station_id: {stn.id()}")
loc_summary = LocationSummary.from_station(stn)
if loc_summary:
for m in loc_summary:
print(
"-----------------------------\n"
f"location_provider: {m.provider}, num_pts: {m.num_pts}\n"
f"latitude mean: {m.latitude_mean}, std_dev: {m.latitude_standard_deviation}\n"
f"longitude mean: {m.longitude_mean}, std_dev: {m.longitude_standard_deviation}\n"
f"altitude mean: {m.altitude_mean}, std_dev: {m.altitude_standard_deviation}"
)
print(
f"-----------------------------\nGNSS timing:\n"
f"GNSS offset at start: {stn.gps_offset_model().intercept}\n"
f"slope: {stn.gps_offset_model().slope}\n"
f"GNSS estimated latency: {stn.gps_offset_model().mean_latency}\n"
f"num_pts: {len(stn.location_sensor().get_gps_timestamps_data())}"
)
else:
print("location data not found.")
print(
f"-----------------------------\ntimesync:\n"
f"best_offset: {stn.timesync_data().best_offset()}, offset_std: {stn.timesync_data().offset_std()}\n"
f"best_latency: {stn.timesync_data().best_latency()}, latency_std: {stn.timesync_data().latency_std()}\n"
f"num_pts: {stn.timesync_data().num_tri_messages()}\n*****************************\n"
)
Functions
def example_of_print_loc_and_timing_summary(stn: Station)
-
An example function that show how you can access location, GNSS, and time sync information and prints it :param stn: Station to get data from
Expand source code
def example_of_print_loc_and_timing_summary(stn: Station): """ An example function that show how you can access location, GNSS, and time sync information and prints it :param stn: Station to get data from """ print(f"station_id: {stn.id()}") loc_summary = LocationSummary.from_station(stn) if loc_summary: for m in loc_summary: print( "-----------------------------\n" f"location_provider: {m.provider}, num_pts: {m.num_pts}\n" f"latitude mean: {m.latitude_mean}, std_dev: {m.latitude_standard_deviation}\n" f"longitude mean: {m.longitude_mean}, std_dev: {m.longitude_standard_deviation}\n" f"altitude mean: {m.altitude_mean}, std_dev: {m.altitude_standard_deviation}" ) print( f"-----------------------------\nGNSS timing:\n" f"GNSS offset at start: {stn.gps_offset_model().intercept}\n" f"slope: {stn.gps_offset_model().slope}\n" f"GNSS estimated latency: {stn.gps_offset_model().mean_latency}\n" f"num_pts: {len(stn.location_sensor().get_gps_timestamps_data())}" ) else: print("location data not found.") print( f"-----------------------------\ntimesync:\n" f"best_offset: {stn.timesync_data().best_offset()}, offset_std: {stn.timesync_data().offset_std()}\n" f"best_latency: {stn.timesync_data().best_latency()}, latency_std: {stn.timesync_data().latency_std()}\n" f"num_pts: {stn.timesync_data().num_tri_messages()}\n*****************************\n" )
Classes
class LocationSummary (name: str, provider: str, latitude_mean: float, latitude_standard_deviation: float, longitude_mean: float, longitude_standard_deviation: float, altitude_mean: Optional[float], altitude_standard_deviation: float, num_pts: int)
-
Summary of a Location. Includes the location sensor's name, source of data (provider), number of points, and the mean and standard deviation of latitude, longitude, and altitude.
Expand source code
@dataclass_json @dataclass class LocationSummary: """ Summary of a Location. Includes the location sensor's name, source of data (provider), number of points, and the mean and standard deviation of latitude, longitude, and altitude. """ name: str provider: str latitude_mean: float latitude_standard_deviation: float longitude_mean: float longitude_standard_deviation: float altitude_mean: Optional[float] altitude_standard_deviation: float num_pts: int @staticmethod def from_station(stn: Station) -> Optional[List["LocationSummary"]]: """ :param stn: Station to get data from :return: List of LocationSummary grouped by provider or None """ loc = stn.find_loc_for_stats() if loc: samples: np.ndarray = loc.samples() if loc.num_samples() == 1: return [ LocationSummary( loc.name, LocationProvider(int(samples[LOCATION_PROVIDER_IDX][0])).name, samples[LATITUDE_IDX][0], 0.0, samples[LONGITUDE_IDX][0], 0.0, samples[ALTITUDE_IDX][0], 0.0, 1, ) ] # for each provider, create a new entry in the dictionary or append new data loc_prov_to_data: dict = {} lat_samples: np.ndarray = samples[LATITUDE_IDX] lng_samples: np.ndarray = samples[LONGITUDE_IDX] for j in range(min(len(lat_samples), len(lng_samples))): if (not math.isnan(lat_samples[j])) and (not math.isnan(lng_samples[j])): prov = LocationProvider(int(samples[LOCATION_PROVIDER_IDX][j])).name data = np.array( [ [samples[LATITUDE_IDX][j]], [samples[LONGITUDE_IDX][j]], [samples[ALTITUDE_IDX][j]], ] ) loc_prov_to_data[prov] = ( data if prov not in loc_prov_to_data.keys() else np.concatenate([loc_prov_to_data[prov], data], 1) ) loc_sums = [] for provider, loc_data in loc_prov_to_data.items(): loc_sums.append( LocationSummary( loc.name, provider, loc_data[0].mean(), loc_data[0].std(), loc_data[1].mean(), loc_data[1].std(), loc_data[2].mean(), loc_data[2].std(), len(loc_data[0]), ) ) return loc_sums return None
Class variables
var altitude_mean : Optional[float]
var altitude_standard_deviation : float
var latitude_mean : float
var latitude_standard_deviation : float
var longitude_mean : float
var longitude_standard_deviation : float
var name : str
var num_pts : int
var provider : str
Static methods
def from_dict(kvs: Union[dict, list, str, int, float, bool, ForwardRef(None)], *, infer_missing=False) ‑> ~A
-
Expand source code
@classmethod def from_dict(cls: Type[A], kvs: Json, *, infer_missing=False) -> A: return _decode_dataclass(cls, kvs, infer_missing)
def from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) ‑> ~A
-
Expand source code
@classmethod def from_json(cls: Type[A], s: JsonData, *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) -> A: kvs = json.loads(s, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, **kw) return cls.from_dict(kvs, infer_missing=infer_missing)
def from_station(stn: Station) ‑> Optional[List[LocationSummary]]
-
:param stn: Station to get data from :return: List of LocationSummary grouped by provider or None
Expand source code
@staticmethod def from_station(stn: Station) -> Optional[List["LocationSummary"]]: """ :param stn: Station to get data from :return: List of LocationSummary grouped by provider or None """ loc = stn.find_loc_for_stats() if loc: samples: np.ndarray = loc.samples() if loc.num_samples() == 1: return [ LocationSummary( loc.name, LocationProvider(int(samples[LOCATION_PROVIDER_IDX][0])).name, samples[LATITUDE_IDX][0], 0.0, samples[LONGITUDE_IDX][0], 0.0, samples[ALTITUDE_IDX][0], 0.0, 1, ) ] # for each provider, create a new entry in the dictionary or append new data loc_prov_to_data: dict = {} lat_samples: np.ndarray = samples[LATITUDE_IDX] lng_samples: np.ndarray = samples[LONGITUDE_IDX] for j in range(min(len(lat_samples), len(lng_samples))): if (not math.isnan(lat_samples[j])) and (not math.isnan(lng_samples[j])): prov = LocationProvider(int(samples[LOCATION_PROVIDER_IDX][j])).name data = np.array( [ [samples[LATITUDE_IDX][j]], [samples[LONGITUDE_IDX][j]], [samples[ALTITUDE_IDX][j]], ] ) loc_prov_to_data[prov] = ( data if prov not in loc_prov_to_data.keys() else np.concatenate([loc_prov_to_data[prov], data], 1) ) loc_sums = [] for provider, loc_data in loc_prov_to_data.items(): loc_sums.append( LocationSummary( loc.name, provider, loc_data[0].mean(), loc_data[0].std(), loc_data[1].mean(), loc_data[1].std(), loc_data[2].mean(), loc_data[2].std(), len(loc_data[0]), ) ) return loc_sums return None
def schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) ‑> dataclasses_json.mm.SchemaF[~A]
-
Expand source code
@classmethod def schema(cls: Type[A], *, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) -> SchemaType: Schema = build_schema(cls, DataClassJsonMixin, infer_missing, partial) if unknown is None: undefined_parameter_action = _undefined_parameter_action_safe(cls) if undefined_parameter_action is not None: # We can just make use of the same-named mm keywords unknown = undefined_parameter_action.name.lower() return Schema(only=only, exclude=exclude, many=many, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown)
Methods
def to_dict(self, encode_json=False) ‑> Dict[str, Union[dict, list, str, int, float, bool, ForwardRef(None)]]
-
Expand source code
def to_dict(self, encode_json=False) -> Dict[str, Json]: return _asdict(self, encode_json=encode_json)
def to_json(self, *, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Union[int, str, ForwardRef(None)] = None, separators: Tuple[str, str] = None, default: Callable = None, sort_keys: bool = False, **kw) ‑> str
-
Expand source code
def to_json(self, *, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Optional[Union[int, str]] = None, separators: Tuple[str, str] = None, default: Callable = None, sort_keys: bool = False, **kw) -> str: return json.dumps(self.to_dict(encode_json=False), cls=_ExtendedEncoder, skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw)