Exemplo n.º 1
0
    def heatmap(self):

        csi_trace = self.csi_data.frames
        finalEntry, no_frames, no_subcarriers = get_CSI(self.csi_data)
        if len(finalEntry.shape) == 4:
            #>1 antenna stream.
            #Loading the first for ease.
            finalEntry = finalEntry[:, :, 3, 0]

        # from CSIKit.filters.wavelets.dwt import denoise
        # finalEntry = denoise(finalEntry)

        #Transpose to get subcarriers * amplitude.
        finalEntry = np.transpose(finalEntry)

        x_label = "Time (s)"
        try:
            x = self.csi_data.timestamps
            x = [timestamp - x[0] for timestamp in x]
        except AttributeError as e:
            #No timestamp in frame. Likely an IWL entry.
            #Will be moving timestamps to CSIData to account for this.
            x = [0]

        if sum(x) == 0:
            #Some files have invalid timestamp_low values which means we can't plot based on timestamps.
            #Instead we'll just plot by frame count.

            xlim = no_frames

            x_label = "Frame No."
        else:
            xlim = max(x)

        limits = [0, xlim, 1, no_subcarriers]
        # limits = [0, xlim, -64, 63]

        #TODO Add options for filtering.
        # for x in range(no_subcarriers):
        #     hampelData = hampel(finalEntry[x], 5, 3)
        #     runningMeanData = running_mean(hampelData, 20)
        #     # smoothedData = dynamic_detrend(runningMeanData, 5, 3, 1.2, 10)
        #     # doubleHampel = hampel(smoothedData, 10, 3)

        #     finalEntry[x] = bandpass(9, 1, 2, Fs, runningMeanData)
        #     # for i in range(0, 140):
        #     #     finalEntry[x][i] = 0

        _, ax = plt.subplots()
        im = ax.imshow(finalEntry, cmap="jet", extent=limits, aspect="auto")

        cbar = ax.figure.colorbar(im, ax=ax)
        cbar.ax.set_ylabel("Amplitude (dBm)")

        plt.xlabel(x_label)
        plt.ylabel("Subcarrier Index")

        plt.title(self.csi_data.filename)

        plt.show()
Exemplo n.º 2
0
def generate_json(path: str, metric: str = "amplitude") -> str:
    """
        This function converts a csi_trace into the json format. It works for single entry or the whole trace.

        Parameters:
            path (str): Path to CSI file location.
    """
    def default(prop):
        if "complex" in str(type(prop)):
            return str(prop)
        if "numpy" in str(type(prop)):
            return prop.tolist()
        if "__dict__" in dir(prop):
            return prop.__dict__
        else:
            print("Prop has no __dict__ {}: \n {}".format(type(prop), prop))

    reader = get_reader(path)
    csi_data = reader.read_file(path)
    csi_matrix, no_frames, no_subcarriers = get_CSI(csi_data, metric)

    print("CSI Shape: {}".format(csi_matrix.shape))
    print("Number of Frames: {}".format(no_frames))
    print("Generating CSI {}...".format(metric))

    json_str = json.dumps(csi_matrix, default=default, indent=True)
    return json_str
Exemplo n.º 3
0
    def prepostfilter(self):

        csi_trace = self.csi_data.frames
        finalEntry, no_frames, _ = get_CSI(self.csi_data)

        finalEntry = finalEntry[15]

        hampelData = hampel(finalEntry, 10)
        smoothedData = running_mean(hampelData.copy(), 10)

        y = finalEntry
        y2 = hampelData
        y3 = smoothedData

        x = list([x.timestamp for x in csi_trace])

        if sum(x) == 0:
            x = np.arange(0, no_frames, 1)

        plt.plot(x, y, label="Raw")
        plt.plot(x, y2, label="Hampel")
        plt.plot(x, y3, "r", label="Hampel + Running Mean")

        plt.xlabel("Time (s)")
        plt.ylabel("Amplitude (dBm)")
        plt.legend(loc="upper right")

        plt.show()
Exemplo n.º 4
0
def load_csi_data(csi_data,
                  subcarrier_range=ALL_CHANNELS,
                  target_sample_rate=10,
                  lowpass=True):

    frames = csi_data.frames

    #Identify the need for source resampling.
    no_frames = len(frames)
    first_timestamp = frames[0].timestamp
    last_timestamp = frames[-1].timestamp

    final_timestamp = last_timestamp - first_timestamp
    average_sample_rate = no_frames / final_timestamp

    #Check the average sample rate is close enough to that we'd expect.
    if abs(average_sample_rate - DEFAULT_FS) > 10:

        #Ideally we'd like to use some interpolation.
        #But supposedly scipy's interp1d is slow.
        #For now, we'll stick with downsampling since we're in control of data capture.

        if average_sample_rate > DEFAULT_FS:
            downsample_factor = int(average_sample_rate / DEFAULT_FS)
            frames = frames[::downsample_factor]

    #At this point, our trace object should have an avg sampling rate of 100Hz.

    #Retrieve CSI for the data we've got now.
    csi, _, _ = get_CSI(csi_data)
    timestamps = csi_data.timestamps
    # timestamps = [x["timestamp"] for x in trace]
    # timestamps_unscaled = [x["timestamp_low"] for x in trace]

    #Filter out unwanted subcarriers.
    csi = csi[[x for x in range(256) if x not in USELESS_SUBCARRIERS]]
    csi = csi[[x for x in subcarrier_range]]

    #Handle Lowpass filter.
    if lowpass:
        sampling_rate = 100  #Hz
        lowpass_cutoff = 10  #Hz
        order = 5  #n

        for x in range(csi.shape[0]):
            csi[x] = filters.lowpass(csi[x], lowpass_cutoff, sampling_rate,
                                     order)
        csi = np.nan_to_num(csi)

    csi_trans = np.transpose(csi)

    #Downsample to 10Hz.
    csi_trans = csi_trans[::10]
    timestamps = timestamps[::10]

    return csi_trans, timestamps, timestamps
Exemplo n.º 5
0
    def plotAllSubcarriers(self):

        finalEntry, no_frames, _ = get_CSI(self.csi_data)

        for x in finalEntry:
            plt.plot(np.arange(no_frames) / 20, x)

        plt.xlabel("Time (s)")
        plt.ylabel("Amplitude (dBm)")
        plt.legend(loc="upper right")

        plt.show()
Exemplo n.º 6
0
def generate_npz(path: str, dest: str, metric: str = "amplitude"):
    reader = get_reader(path)
    csi_data = reader.read_file(path)

    if dest[-4:] != ".npz":
        dest += ".npz"

    csi_matrix, _, _ = get_CSI(csi_data, metric)
    np.savez_compressed(dest, csi_matrix)

    print("CSI matrix with shape: {}".format(csi_matrix.shape))
    print("Generating CSI {}...".format(metric))
    print("File written to: {}".format(dest))
Exemplo n.º 7
0
    def get_metadata(self) -> CSIMetadata:
        chipset = self.chipset

        bandwidth = self.bandwidth

        unmodified_csi_matrix = self.frames[0].csi_matrix
        _, no_frames, no_subcarriers = get_CSI(self)

        rx_count = (0, 0)
        tx_count = (0, 0)

        if len(unmodified_csi_matrix.shape) <= 2:
            rx_count, tx_count = (1, 1)
        elif len(unmodified_csi_matrix.shape) == 3:
            rx_count, tx_count = unmodified_csi_matrix.shape[1:]

        antenna_config_string = "{} Rx, {} Tx".format(rx_count, tx_count)

        timestamps = self.timestamps
        final_timestamp = timestamps[-1]

        #Check if timestamp is relative or epoch.

        time_length = 0
        if len(str(final_timestamp)) > 9:
            #Likely an epoch timestamp.
            #Get diff between first and last.
            time_length = final_timestamp - timestamps[0]
        else:
            time_length = float(final_timestamp)

        if final_timestamp == 0:
            average_sample_rate = 0
        else:
            average_sample_rate = no_frames/time_length

        data = {
            "chipset": chipset,
            "bandwidth": bandwidth,
            "antenna_config": antenna_config_string,
            "frames": no_frames,
            "subcarriers": no_subcarriers,
            "time_length": time_length,
            "average_sample_rate": average_sample_rate,
            "csi_shape": unmodified_csi_matrix.shape
        }    

        return CSIMetadata(data)
Exemplo n.º 8
0
def generate_csv(path: str, dest: str, metric: str = "amplitude"):
    reader = get_reader(path)
    csi_data = reader.read_file(path)

    csi_matrix, no_frames, no_subcarriers = get_CSI(csi_data, metric)
    no_rx, no_tx = csi_matrix.shape[2:]

    print("CSI Shape: {}".format(csi_matrix.shape))
    print("Number of Frames: {}".format(no_frames))
    print("Generating CSI {}...".format(metric))
    print("CSV dimensions: {} Rows, {} Columns".format(
        no_frames, no_subcarriers * no_rx * no_tx))

    csv_header = []
    for subcarrier in range(no_subcarriers):
        for rx in range(no_rx):
            for tx in range(no_tx):
                csv_header.append("Sub {} RXTX {}/{}".format(
                    subcarrier, rx, tx))

    with open(dest, "w", newline="") as csv_file:
        writer = csv.writer(csv_file, delimiter=",")
        writer.writerow(csv_header)

        for frame in range(no_frames):
            frame_data = csi_matrix[frame]
            row_data = []

            for subcarrier in range(no_subcarriers):
                subcarrier_data = frame_data[subcarrier]
                for rx in range(no_rx):
                    rx_data = subcarrier_data[rx]
                    for tx in range(no_tx):
                        tx_data = rx_data[tx]
                        row_data.append(tx_data)

            writer.writerow(row_data)

    print("File written to: {}".format(dest))
Exemplo n.º 9
0
    def get_metadata(self) -> CSIMetadata:
        chipset = self.chipset

        bandwidth = self.bandwidth

        unmodified_csi_matrix = self.frames[0].csi_matrix
        _, no_frames, no_subcarriers = get_CSI(self)

        rx_count = (0, 0)
        tx_count = (0, 0)

        if len(unmodified_csi_matrix.shape) <= 2:
            rx_count, tx_count = (1, 1)
        elif len(unmodified_csi_matrix.shape) == 3:
            rx_count, tx_count = unmodified_csi_matrix.shape[1:]

        antenna_config_string = "{} Rx, {} Tx".format(rx_count, tx_count)

        timestamps = self.timestamps
        final_timestamp = timestamps[-1]

        #Check if timestamp is relative or epoch.

        time_length = 0
        if len(str(final_timestamp)) > 9:
            #Likely an epoch timestamp.
            #Get diff between first and last.
            time_length = final_timestamp - timestamps[0]
        else:
            time_length = round(float(final_timestamp), 1)

        if final_timestamp == 0:
            average_sample_rate = 0
        else:
            average_sample_rate = round(no_frames/time_length, 1)

        rss_total = []
        if hasattr(self.frames[0], "rssi"):
            rss_total = [x.rssi for x in self.frames]
        else:
            # Must sum a/b/c.
            for frame in self.frames:
                total_rss_for_frame = 0
                divisor = 0
                if frame.rssi_a != 0:
                    total_rss_for_frame += frame.rssi_a
                    divisor += 1
                if frame.rssi_b != 0:
                    total_rss_for_frame += frame.rssi_b
                    divisor += 1
                if frame.rssi_c != 0:
                    total_rss_for_frame += frame.rssi_c
                    divisor += 1
                total_rss_for_frame /= divisor
                rss_total.append(total_rss_for_frame)

        average_rssi = round(np.mean(rss_total), 1)

        data = {
            "chipset": chipset,
            "bandwidth": bandwidth,
            "antenna_config": antenna_config_string,
            "frames": no_frames,
            "subcarriers": no_subcarriers,
            "time_length": time_length,
            "average_sample_rate": average_sample_rate,
            "average_rssi": average_rssi,
            "csi_shape": unmodified_csi_matrix.shape
        }    

        return CSIMetadata(data)