def heatmap_beam_pattern(self, save_fig=True): ''' beampattern heatmap only available for frequency domain beamforming case : draw beampatten for heatmap. There will be as many subplots as beamforming numbers. ''' if self._beamforming_cout == 0: raise ValueError( 'No beamforming to analysis! Please append one firstly!') beamforming_dict = self._beamforming_list[0] if beamforming_dict.get('beam_domain') == 'time': raise ValueError( 'Time domain beamforming donnot support heatmap plot!') print('This may take a few seconds. Please wating...') figsize = (10, 5) if self._beamforming_cout == 1 else ( 10, 3 * self._beamforming_cout) plot = Plot(figsize=figsize, subplot_rows=self._beamforming_cout) plot.append_axes_combo() xticks = np.arange(0, len(constants.get('angle_range')), 60) yticks = np.arange(0, 900, 100) xticklabels = np.arange( 0, len(constants.get('angle_range')), 60, dtype=int) / 2.0 yticklabels = np.linspace(8, 0, num=9, endpoint=True, dtype=int) freq_range = np.linspace(8000, 1, num=800, endpoint=True) for beam_index, beam in enumerate(self._beamforming_list): response_matrix = np.zeros( (len(freq_range), len(constants.get('angle_range')))) for freq_index, freq in enumerate(freq_range): response_matrix[freq_index:] = beam[ 'beam_instance'].beam_pattern(freq) plot.plot_heatmap(response_matrix, label_pad=-65, subplot_index=beam_index) plot.set_pipeline(title=beam['beam_instance'].beam_label, xticks=xticks, yticks=yticks, xticklabels=[int(tick) for tick in xticklabels], yticklabels=yticklabels, xlabel='Azimuth Angle[Deg]', ylabel='Freq[kHz]', wait_for_user=False, subplot_index=beam_index) if self._beamforming_cout > 1: plot.suptitle( 'Beampattern Heatmap Compare for Different Beamforming', hspace=0.5) if save_fig: fig_name = self.fig_name('Beampattern_Heatmap') plot.save_figure(fig_name) plot.wait_for_user()
def beam_pattern(self, polar, save_fig): ''' plot either beamforming or beamforming group's beampattern Case1 -- if the beamforming is a time domain beamforming, either ploar or catersian all the beam instance are plotted in the same figure, because it's frequency invariant. Case2-- if the beamforming is a frequency domain beamforming, then if polar, it will be plotted in 4 figures, every figure represents a single frequency. if catesian, the figure number is equal to the beamforming instance number. One figure represents a beamforming, the different frequency plotted in this same figure. Parameters ---------- polar: bool True or False save_fig: bool True of False ''' if self._beamforming_cout == 0: raise ValueError( 'No beamforming to analysis! Please append one firstly!') beamforming_dict = self._beamforming_list[0] coordinate = 'Polar' if polar else 'Cartesian' title = '{coordinate} Beampattern for {domain}Domain {dtype}Beamforming'.format( coordinate=coordinate, domain=(beamforming_dict.get('beam_domain')).capitalize(), dtype=(beamforming_dict.get('beam_type')).capitalize()) if polar: sweep_angle = np.concatenate( (constants.get('angle_range'), (constants.get('angle_range') + np.pi)), axis=0) xlim = (0, 2 * np.pi) else: sweep_angle = np.degrees(constants.get('angle_range')) xlim = (0, 180) if beamforming_dict.get('beam_domain') == 'time': plot = Plot(figsize=(6, 6)) if polar else Plot(figsize=(8, 5)) plot.append_axes_combo(polar=polar) axis_limit_max = 0 axis_limit_min = 0 for beam_index, beam in enumerate(self._beamforming_list): response = beam['beam_instance'].beam_pattern() axis_limit_max = np.maximum(axis_limit_max, np.max(response)) axis_limit_min = np.minimum(axis_limit_min, np.min(response)) if polar: response = np.concatenate( (response, np.fliplr([response])[0]), axis=0) plot.plot_vector(response, sweep_angle, label=beam['beam_instance'].beam_label) plot.set_pipeline(xlim=xlim, ylim=(axis_limit_min - 1, axis_limit_max + 1), title=title, xlabel='Azimuth Angle[Deg]', wait_for_user=False) plot.set_legend(loc=(0.7, 0.01), fontsize=6) elif beamforming_dict.get('beam_domain') == 'frequency': if polar: mini_freq_range = constants.get('freq_range_mini') plot = Plot(figsize=(8, 8), subplot_cols=2, subplot_rows=2) plot.append_axes_combo(polar=True) # axis_limit_max = 0 # axis_limit_min = 0 for beam_index, beam in enumerate(self._beamforming_list): for freq_index, freq in enumerate(mini_freq_range): # get response response = beam['beam_instance'].beam_pattern(freq) # axis_limit_max = np.maximum(axis_limit_max, np.max(response)) # axis_limit_min = np.minimum(axis_limit_min, np.min(response)) response = np.concatenate( (response, np.fliplr([response])[0]), axis=0) # plot plot.plot_vector( response, sweep_angle, label=beam['beam_instance'].beam_label, subplot_index=freq_index) plot.set_pipeline( xlim=(0, 2 * np.pi), ylim=(-50, 1), title='', xlabel='Azimuth Angle[Deg]_{}Hz'.format(freq), wait_for_user=False, subplot_index=freq_index) plot.set_legend(loc=(0.5, 0.01), fontsize=6, subplot_index=3) plot.suptitle(title) else: plot = Plot(figsize=(8, 4 * self._beamforming_cout), subplot_rows=self._beamforming_cout) plot.append_axes_combo() axis_limit_max = 0 axis_limit_min = 0 for beam_index, beam in enumerate(self._beamforming_list): for freq in constants.get('freq_range_small'): response = beam['beam_instance'].beam_pattern(freq) axis_limit_max = np.maximum(axis_limit_max, np.max(response)) axis_limit_min = np.minimum(axis_limit_min, np.min(response)) plot.plot_vector(response, np.degrees( constants.get('angle_range')), label='{} kHz'.format(freq / 1000), subplot_index=beam_index) plot.set_pipeline( title=beam['beam_instance'].beam_label, xlim=xlim, ylim=(axis_limit_min - 1, axis_limit_max + 1), xlabel='Azimuth Angle[Deg]', ylabel='Beampatten[dB]', wait_for_user=False, subplot_index=beam_index) plot.set_legend(subplot_index=self._beamforming_cout - 1) if self._beamforming_cout > 1: plot.suptitle(title, 0.5) if save_fig: fig_name = self.fig_name( 'Beampattern_{coordinate}'.format(coordinate=coordinate)) plot.save_figure(fig_name) plot.wait_for_user()