def test_unevenly_sampled_channel_int64_payload(self): correct = [1, 2, 3, 4, 5] unevenly_sampled_channel = mock.set_payload( self.unevenly_sampled_channel, numpy.int64, correct) self.assertArraysEqual( reader_utils.extract_payload(unevenly_sampled_channel), numpy.array(correct))
def test_evenly_sampled_channel_float64_payload(self): correct = [1.0, 2.0, 3.0, 4.0, 5.0] evenly_sampled_channel = mock.set_payload(self.evenly_sampled_channel, numpy.float64, correct) self.assertArraysEqual( reader_utils.extract_payload(evenly_sampled_channel), numpy.array(correct))
def test_evenly_sampled_channel_uint32_payload(self): correct = [1, 2, 3, 4, 5] evenly_sampled_channel = mock.set_payload(self.evenly_sampled_channel, numpy.uint32, correct) self.assertArraysEqual( reader_utils.extract_payload(evenly_sampled_channel), numpy.array(correct))
def time_sync_data_from_raw_packet( packet: Union[RedvoxPacketM, RedvoxPacket]) -> TimeSyncData: """ :param packet: data packet to get time sync data from :return: TimeSyncData object from data packet """ tsd: TimeSyncData if isinstance(packet, RedvoxPacketM): exchanges: List[float] = reduce( lambda acc, ex: acc + [ex.a1, ex.a2, ex.a3, ex.b1, ex.b2, ex.b3], packet.timing_information.synch_exchanges, []) tsd = TimeSyncData( packet.station_information.id, packet.sensors.audio.sample_rate, len(packet.sensors.audio.samples.values), packet.timing_information.app_start_mach_timestamp, packet.timing_information.server_acquisition_arrival_timestamp, packet.timing_information.packet_start_mach_timestamp, packet.timing_information.packet_end_mach_timestamp, exchanges, packet.timing_information.best_latency, packet.timing_information.best_offset) else: mtz: float = np.nan best_latency: float = np.nan best_offset: float = np.nan for i, v in enumerate(packet.metadata): plus_1: int = i + 1 try: if v == "machTimeZero" and plus_1 < len(packet.metadata): mtz = float(packet.metadata[plus_1]) if v == "bestLatency" and plus_1 < len(packet.metadata): best_latency = float(packet.metadata[plus_1]) if v == "bestOffset" and plus_1 < len(packet.metadata): best_offset = float(packet.metadata[plus_1]) except (KeyError, ValueError): continue # Get synch exchanges exchanges: Optional[np.ndarray] = None ch: api900_pb2.UnevenlySampledChannel for ch in packet.unevenly_sampled_channels: if api900_pb2.TIME_SYNCHRONIZATION in ch.channel_types: exchanges = util_900.extract_payload(ch) tsd = TimeSyncData( packet.redvox_id, packet.evenly_sampled_channels[0].sample_rate_hz, util_900.payload_len(packet.evenly_sampled_channels[0]), mtz, packet.evenly_sampled_channels[0]. first_sample_timestamp_epoch_microseconds_utc, packet.server_timestamp_epoch_microseconds_utc, packet.app_file_start_timestamp_machine, list(exchanges), best_latency, best_offset, ) return tsd
def set_payload(self, payload_values: typing.Union[numpy.ndarray, typing.List], pl_type: constants.PayloadType, should_compute_stats=True): """ sets the payload to an interleaved channel with step number of arrays interleaved together. :param should_compute_stats: Whether the statistics should be computed or not (optional default to True) :param payload_values: Interleaved payload values :param pl_type: payload type """ # if len(payload_values) < 1: # raise exceptions.ReaderException("Channel must not be empty and number of arrays must not be less than # 1.") # Convert to numpy array is necessary payload_values = reader_utils.to_array(payload_values) # clear all other payloads self.protobuf_channel.byte_payload.ClearField("payload") self.protobuf_channel.uint32_payload.ClearField("payload") self.protobuf_channel.uint64_payload.ClearField("payload") self.protobuf_channel.int32_payload.ClearField("payload") self.protobuf_channel.int64_payload.ClearField("payload") self.protobuf_channel.float32_payload.ClearField("payload") self.protobuf_channel.float64_payload.ClearField("payload") # set the payload based on the type of data if pl_type == constants.PayloadType.BYTE_PAYLOAD: self.protobuf_channel.byte_payload.payload = payload_values elif pl_type == constants.PayloadType.UINT32_PAYLOAD: self.protobuf_channel.uint32_payload.payload.extend(payload_values) elif pl_type == constants.PayloadType.UINT64_PAYLOAD: self.protobuf_channel.uint64_payload.payload.extend(payload_values) elif pl_type == constants.PayloadType.INT32_PAYLOAD: self.protobuf_channel.int32_payload.payload.extend(payload_values) elif pl_type == constants.PayloadType.INT64_PAYLOAD: self.protobuf_channel.int64_payload.payload.extend(payload_values) elif pl_type == constants.PayloadType.FLOAT32_PAYLOAD: self.protobuf_channel.float32_payload.payload.extend( payload_values) elif pl_type == constants.PayloadType.FLOAT64_PAYLOAD: self.protobuf_channel.float64_payload.payload.extend( payload_values) else: raise TypeError("Unknown payload type to set.") if len(payload_values) < 1: self.payload = payload_values else: self.payload = reader_utils.extract_payload(self.protobuf_channel) # calculate the means, std devs, and medians if should_compute_stats: self.update_stats()
def set_channel(self, channel: typing.Union[api900_pb2.EvenlySampledChannel, api900_pb2.UnevenlySampledChannel]): """ Sets the protobuf channel :param channel: protobuf channel """ self.protobuf_channel = channel self.sensor_name = channel.sensor_name self.channel_types = reader_utils.repeated_to_list( channel.channel_types) self.payload = reader_utils.extract_payload(channel) self.metadata = reader_utils.repeated_to_list(channel.metadata) self.value_means = reader_utils.repeated_to_array(channel.value_means) self.value_stds = reader_utils.repeated_to_array(channel.value_stds) self.value_medians = reader_utils.repeated_to_array( channel.value_medians) self.channel_type_index = { self.channel_types[i]: i for i in range(len(self.channel_types)) }
def __init__(self, channel: typing.Optional[ typing.Union[api900_pb2.EvenlySampledChannel, api900_pb2.UnevenlySampledChannel]] = None): """ Initializes this interleaved channel object. :param channel: Either a protobuf evenly or unevenly sampled channel. note: value_means, value_medians, value_stds, and channel_type_index are only set during initialization or when payload is altered payload should only be altered by set_payload or set_deinterleaved_payload due to the extra data values that are required to correctly set the protobuf_channel """ if channel is None: self.protobuf_channel = None self.sensor_name = None self.channel_types = [0] self.payload = [0] self.metadata = [] self.value_means = [] self.value_stds = [] self.value_medians = [] self.channel_type_index = [] else: self.protobuf_channel: typing.Union[ api900_pb2.EvenlySampledChannel, api900_pb2.UnevenlySampledChannel] = channel """Reference to the original protobuf channel""" self.sensor_name: str = channel.sensor_name """Provided sensor name""" self.channel_types: typing.List[typing.Union[ api900_pb2.EvenlySampledChannel, api900_pb2. UnevenlySampledChannel]] = reader_utils.repeated_to_list( channel.channel_types) """List of channel type constant enumerations""" self.payload: numpy.ndarray = reader_utils.extract_payload(channel) """This channels payload as a numpy array of either floats or ints""" self.metadata: typing.List[str] = reader_utils.repeated_to_list( channel.metadata) """This channels list of metadata""" self.value_means: numpy.ndarray = reader_utils.repeated_to_array( channel.value_means) """Interleaved array of mean values""" self.value_stds: numpy.ndarray = reader_utils.repeated_to_array( channel.value_stds) """Interleaved array of standard deviations of values""" self.value_medians: numpy.ndarray = reader_utils.repeated_to_array( channel.value_medians) """Interleaves array of median values""" self.channel_type_index: typing.Dict[ api900_pb2.ChannelType, int] = { self.channel_types[i]: i for i in range(len(self.channel_types)) } """Contains a mapping of channel type to index in channel_types array"""
def from_raw_packets( self, packets: List[Union[RedvoxPacketM, RedvoxPacket]]) -> 'TimeSyncAnalysis': """ converts packets into TimeSyncData objects, then performs analysis :param packets: list of WrappedRedvoxPacketM to convert :return: modified version of self """ timesync_data: List[TimeSyncData] = [] packet: Union[RedvoxPacketM, RedvoxPacket] for packet in packets: tsd: TimeSyncData if isinstance(packet, RedvoxPacketM): exchanges: List[float] = reduce( lambda acc, ex: acc + [ex.a1, ex.a2, ex.a3, ex.b1, ex.b2, ex.b3], packet.timing_information.synch_exchanges, []) tsd = TimeSyncData( packet.station_information.id, packet.sensors.audio.sample_rate, len(packet.sensors.audio.samples.values), packet.timing_information.app_start_mach_timestamp, packet. timing_information.server_acquisition_arrival_timestamp, packet.timing_information.packet_start_mach_timestamp, packet.timing_information.packet_end_mach_timestamp, exchanges, packet.timing_information.best_latency, packet.timing_information.best_offset) else: mtz: float = np.nan best_latency: float = np.nan best_offset: float = np.nan for i, v in enumerate(packet.metadata): plus_1: int = i + 1 try: if v == "machTimeZero" and plus_1 < len( packet.metadata): mtz = float(packet.metadata[plus_1]) if v == "bestLatency" and plus_1 < len( packet.metadata): best_latency = float(packet.metadata[plus_1]) if v == "bestOffset" and plus_1 < len(packet.metadata): best_offset = float(packet.metadata[plus_1]) except (KeyError, ValueError): continue # Get synch exchanges exchanges: Optional[np.ndarray] = None ch: api900_pb2.UnevenlySampledChannel for ch in packet.unevenly_sampled_channels: if api900_pb2.TIME_SYNCHRONIZATION in ch.channel_types: exchanges = util_900.extract_payload(ch) tsd = TimeSyncData( packet.redvox_id, packet.evenly_sampled_channels[0].sample_rate_hz, util_900.payload_len(packet.evenly_sampled_channels[0]), mtz, packet.evenly_sampled_channels[0]. first_sample_timestamp_epoch_microseconds_utc, packet.server_timestamp_epoch_microseconds_utc, packet.app_file_start_timestamp_machine, list(exchanges), best_latency, best_offset, ) timesync_data.append(tsd) self.timesync_data = timesync_data if len(self.timesync_data) > 0: self.evaluate_and_validate_data() return self