From 67c033bb40655768d7d1f1ec30cf445082113c27 Mon Sep 17 00:00:00 2001 From: francescamen Date: Mon, 12 Jun 2023 10:51:02 -0400 Subject: [PATCH] added CSI_doppler_plot_activities.py --- Python_code/CSI_doppler_plot_activities.py | 83 +++++++++++ Python_code/plots_utility.py | 158 +++++++++++++++++++++ README.md | 7 +- 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 Python_code/CSI_doppler_plot_activities.py diff --git a/Python_code/CSI_doppler_plot_activities.py b/Python_code/CSI_doppler_plot_activities.py new file mode 100644 index 0000000..091c71e --- /dev/null +++ b/Python_code/CSI_doppler_plot_activities.py @@ -0,0 +1,83 @@ + +import argparse +import numpy as np +import pickle +from os import listdir +from plots_utility import plt_fft_doppler_activities, plt_fft_doppler_activities_compact, \ + plt_fft_doppler_activity_single, plt_fft_doppler_activities_compact_2 + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('dir', help='Directory of data') + parser.add_argument('sub_dir', help='Sub directory of data') + parser.add_argument('feature_length', help='Length along the feature dimension (height)', type=int) + parser.add_argument('sliding', help='Number of packet for sliding operations', type=int) + parser.add_argument('labels_activities', help='Files names') + parser.add_argument('start_plt', help='Start index to plot', type=int) + parser.add_argument('end_plt', help='End index to plot', type=int) + + args = parser.parse_args() + + activities = np.asarray(['empty', 'sitting', 'walking', 'running', 'jumping']) + + feature_length = args.feature_length + sliding = args.sliding + Tc = 6e-3 + fc = 5e9 + v_light = 3e8 + + exp_dir = args.dir + args.sub_dir + '/' + + labels_activities = args.labels_activities + csi_label_dict = [] + for lab_act in labels_activities.split(','): + csi_label_dict.append(lab_act) + + traces_activities = [] + for ilab in range(len(csi_label_dict)): + names = [] + all_files = listdir(exp_dir) + activity = csi_label_dict[ilab] + + start_l = 4 + end_l = start_l + len(csi_label_dict[ilab]) + for i in range(len(all_files)): + if all_files[i][start_l:end_l] == csi_label_dict[ilab] and all_files[i][-5] != 'p': + names.append(all_files[i][:-4]) + + names.sort() + + stft_antennas = [] + for name in names: + name_file = exp_dir + name + '.txt' + + with open(name_file, "rb") as fp: # Pickling + stft_sum_1 = pickle.load(fp) + + stft_sum_1_log = 10*np.log10(stft_sum_1) + + stft_sum_1_log = stft_sum_1_log[args.start_plt:min(stft_sum_1_log.shape[0], args.end_plt), :] + + stft_antennas.append(stft_sum_1_log) + + traces_activities.append(stft_antennas) + + name_p = './plots/csi_doppler_activities_' + args.sub_dir + '.pdf' + delta_v = round(v_light / (Tc * fc * feature_length), 3) + antenna = 0 + plt_fft_doppler_activities(traces_activities, antenna, activities, sliding, delta_v, name_p) + + name_p = './plots/csi_doppler_activities_' + '_' + args.sub_dir + '_compact.pdf' + plt_fft_doppler_activities_compact(traces_activities, antenna, activities, sliding, delta_v, name_p) + + traces_activities_reduced = traces_activities + del traces_activities_reduced[2] + name_p = './plots/csi_doppler_activities_' + '_' + args.sub_dir + '_compact_2.pdf' + plt_fft_doppler_activities_compact_2(traces_activities_reduced, antenna, + np.asarray(['empty', 'sitting', 'running', 'jumping']), + sliding, delta_v, name_p) + + name_p = './plots/csi_doppler_single_act.pdf' + antenna = 1 + plt_fft_doppler_activity_single(traces_activities[4], antenna, sliding, delta_v, name_p) diff --git a/Python_code/plots_utility.py b/Python_code/plots_utility.py index a690000..da3d384 100644 --- a/Python_code/plots_utility.py +++ b/Python_code/plots_utility.py @@ -604,3 +604,161 @@ def plt_phase(phase_raw, phase_proc, name_plot): axi.label_outer() plt.savefig(name_plot, bbox_inches='tight') plt.close() + + +def plt_fft_doppler_activities(doppler_spectrum_list, antenna, csi_label_dict, sliding_lenght, delta_v, name_plot): + fig = plt.figure(constrained_layout=True) + fig.set_size_inches(15, 3) + widths = [1, 1, 1, 1, 1, 0.5] + heights = [1] + gs = fig.add_gridspec(ncols=6, nrows=1, width_ratios=widths, height_ratios=heights) + step = 20 + step_x = 5 + ax = [] + for a_i in range(5): + act = doppler_spectrum_list[a_i][antenna] + length_v = mt.floor(act.shape[1] / 2) + factor_v = step * (mt.floor(length_v / step)) + ticks_y = np.arange(length_v - factor_v, length_v + factor_v + 1, step) + ticks_x = np.arange(0, act.shape[0] + 1, int(act.shape[0]/step_x)) + + ax1 = fig.add_subplot(gs[(0, a_i)]) + plt1 = ax1.pcolormesh(act.T, cmap='viridis', linewidth=0, rasterized=True) # , shading='gouraud') + plt1.set_edgecolor('face') + ax1.set_ylabel(r'$v_p \cos \alpha_p$ [m/s]') + ax1.set_xlabel(r'time [s]') + ax1.set_yticks(ticks_y + 0.5) + ax1.set_yticklabels(np.round((ticks_y - length_v) * delta_v, 2)) + ax1.set_xticks(ticks_x) + ax1.set_xticklabels(np.round(ticks_x * sliding_lenght * 6e-3, 2)) + + title_p = csi_label_dict[a_i] + ax1.set_title(title_p) + ax.append(ax1) + + if a_i == 4: + cbar_ax = fig.add_axes([0.92, 0.2, 0.01, 0.7]) + cbar1 = fig.colorbar(plt1, cax=cbar_ax, ticks=[-12, -8, -4, 0]) + cbar1.ax.set_ylabel('normalized power [dB]') + + for axi in ax: + axi.label_outer() + plt.savefig(name_plot, bbox_inches='tight') + plt.close() + + +def plt_fft_doppler_activities_compact(doppler_spectrum_list, antenna, csi_label_dict, sliding_lenght, delta_v, name_plot): + fig = plt.figure(constrained_layout=True) + fig.set_size_inches(8, 5.5) + widths = [1, 1, 1, 1, 1, 1, 0.5] + heights = [1, 1] + gs = fig.add_gridspec(ncols=7, nrows=2, width_ratios=widths, height_ratios=heights) + step = 20 + step_x = 5 + ax = [] + list_plts_pos_row = [0, 0, 1, 1, 1] + list_plts_pos_col_start = [1, 3, 0, 2, 4] + list_plts_pos_col_end = [3, 5, 2, 4, 6] + for a_i in range(5): + act = doppler_spectrum_list[a_i][antenna] + length_v = mt.floor(act.shape[1] / 2) + factor_v = step * (mt.floor(length_v / step)) + ticks_y = np.arange(length_v - factor_v, length_v + factor_v + 1, step) + ticks_x = np.arange(0, act.shape[0] + 1, int(act.shape[0]/step_x)) + + ax1 = fig.add_subplot(gs[list_plts_pos_row[a_i], list_plts_pos_col_start[a_i]:list_plts_pos_col_end[a_i]]) + plt1 = ax1.pcolormesh(act.T, cmap='viridis', linewidth=0, rasterized=True) # , shading='gouraud') + plt1.set_edgecolor('face') + ax1.set_xlabel(r'time [s]') + ax1.set_yticks(ticks_y + 0.5) + if a_i == 0 or a_i == 2: + ax1.set_yticklabels(np.round((ticks_y - length_v) * delta_v, 2)) + ax1.set_ylabel(r'$v_p \cos \alpha_p$ [m/s]') + else: + ax1.set_yticklabels([]) + ax1.set_ylabel('') + ax1.set_xticks(ticks_x) + ax1.set_xticklabels(np.round(ticks_x * sliding_lenght * 6e-3, 2)) + + title_p = csi_label_dict[a_i] + ax1.set_title(title_p) + ax.append(ax1) + + if a_i == 1 or a_i == 4: + cbar_ax = fig.add_axes([0.98, 0.2, 0.02, 0.7]) + cbar1 = fig.colorbar(plt1, cax=cbar_ax, ticks=[-12, -8, -4, 0]) + cbar1.ax.set_ylabel('normalized power [dB]') + + plt.savefig(name_plot, bbox_inches='tight') + plt.close() + + +def plt_fft_doppler_activities_compact_2(doppler_spectrum_list, antenna, csi_label_dict, sliding_lenght, + delta_v, name_plot): + fig = plt.figure(constrained_layout=True) + fig.set_size_inches(6, 5.5) + widths = [1, 1, 0.5] + heights = [1, 1] + gs = fig.add_gridspec(ncols=3, nrows=2, width_ratios=widths, height_ratios=heights) + step = 20 + step_x = 5 + ax = [] + list_plts_pos_row = [0, 0, 1, 1] + list_plts_pos_col = [0, 1, 0, 1] + for a_i in range(4): + act = doppler_spectrum_list[a_i][antenna] + length_v = mt.floor(act.shape[1] / 2) + factor_v = step * (mt.floor(length_v / step)) + ticks_y = np.arange(length_v - factor_v, length_v + factor_v + 1, step) + ticks_x = np.arange(0, act.shape[0] + 1, int(act.shape[0]/step_x)) + + ax1 = fig.add_subplot(gs[list_plts_pos_row[a_i], list_plts_pos_col[a_i]]) + plt1 = ax1.pcolormesh(act.T, cmap='viridis', linewidth=0, rasterized=True) # , shading='gouraud') + plt1.set_edgecolor('face') + ax1.set_xlabel(r'time [s]') + ax1.set_yticks(ticks_y + 0.5) + if a_i == 0 or a_i == 2: + ax1.set_yticklabels(np.round((ticks_y - length_v) * delta_v, 2)) + ax1.set_ylabel(r'$v_p \cos \alpha_p$ [m/s]') + else: + ax1.set_yticklabels([]) + ax1.set_ylabel('') + ax1.set_xticks(ticks_x) + ax1.set_xticklabels(np.round(ticks_x * sliding_lenght * 6e-3, 2)) + + title_p = csi_label_dict[a_i] + ax1.set_title(title_p) + ax.append(ax1) + + if a_i == 1: + cbar_ax = fig.add_axes([0.9, 0.2, 0.03, 0.7]) + cbar1 = fig.colorbar(plt1, cax=cbar_ax, ticks=[-12, -8, -4, 0]) + cbar1.ax.set_ylabel('normalized power [dB]') + + plt.savefig(name_plot, bbox_inches='tight') + plt.close() + + +def plt_fft_doppler_activity_single(input_a, antenna, sliding_lenght, delta_v, name_plot): + fig = plt.figure(constrained_layout=True) + fig.set_size_inches(3, 3) + step = 20 + step_x = 5 + act = input_a[antenna][:340, :] + length_v = mt.floor(act.shape[1] / 2) + factor_v = step * (mt.floor(length_v / step)) + ticks_y = np.arange(length_v - factor_v, length_v + factor_v + 1, step) + ticks_x = np.arange(0, act.shape[0] + 1, int(act.shape[0]/step_x)) + + ax1 = fig.add_subplot() + plt1 = ax1.pcolormesh(act.T, cmap='viridis', linewidth=0, rasterized=True) # , shading='gouraud') + plt1.set_edgecolor('face') + ax1.set_ylabel(r'$v_p \cos \alpha_p$ [m/s]') + ax1.set_xlabel(r'time [s]') + ax1.set_yticks(ticks_y + 0.5) + ax1.set_yticklabels(np.round((ticks_y - length_v) * delta_v, 2)) + ax1.set_xticks(ticks_x) + ax1.set_xticklabels(np.round(ticks_x * sliding_lenght * 6e-3, 1)) + + plt.savefig(name_plot, bbox_inches='tight') + plt.close() diff --git a/README.md b/README.md index 58ed29c..18ce33e 100644 --- a/README.md +++ b/README.md @@ -59,12 +59,17 @@ python CSI_doppler_computation.py <'directory of the reconstructed data'> <'sub- ``` e.g., python CSI_doppler_computation.py ./processed_phase/ S1a,S1b,S1c,S2a,S2b,S3a,S4a,S4b,S5a,S6a,S6b,S7a ./doppler_traces/ 800 800 31 1 -1.2 -To plot the Doppler traces use +To plot the Doppler traces use (first to plot all the antennas, second single antenna for all the activities) ```bash python CSI_doppler_plots_antennas.py <'directory of the reconstructed data'> <'sub-directory of data'> <'length along the feature dimension (height)'> <'sliding length'> <'labels of the activities to be considered'> <'last index to plot'> ``` e.g., python CSI_doppler_plots_antennas.py ./doppler_traces/ S7a 100 1 E,L1,W,R,J1 20000 +```bash +python CSI_doppler_plots_activities.py <'directory of the reconstructed data'> <'sub-directory of data'> <'length along the feature dimension (height)'> <'sliding length'> <'labels of the activities to be considered'> <'first index to plot'> <'last index to plot'> +``` +e.g., python CSI_doppler_plots_activities.py ./doppler_traces/ S7a 100 1 E,L1,W,R,J1 570 1070 + #### Pre-computed Doppler traces If you want to skip the above processing steps, you can find the Doppler traces [in this Google Drive folder](https://drive.google.com/drive/folders/1SilO6VD73Lz8sjZ-KQgFnQ2IKRvggqPg?usp=sharing). In the same folder, the sanitized channel measurements for S2a and S7a are uploaded as examples in ```processed_phase```. Exaples of plots of the Doppler traces are also included.