def gt_blast_center_noise_uneven( sensor_epoch_s: np.array, noise_std_loss_bits: float = 2, frequency_center_hz: Optional[float] = None) -> np.ndarray: """ Construct the GT explosion pulse of Garces (2019) for even or uneven sensor time in Gaussion noise with SNR in bits re signal STD. This is a very flexible variation. :param sensor_epoch_s: array with timestamps for signal in epoch seconds :param noise_std_loss_bits: number of bits below signal standard deviation. Default is 2 :param frequency_center_hz: center frequency in Hz. Optional :return: numpy array with anti-aliased GT explosion pulse with Gaussian noise """ time_duration_s = sensor_epoch_s[-1] - sensor_epoch_s[0] if frequency_center_hz: pseudo_period_s = 1 / frequency_center_hz else: pseudo_period_s = time_duration_s / 4. # Convert to seconds time_center_s = sensor_epoch_s - sensor_epoch_s[0] - time_duration_s / 2. sig_gt = gt_blast_period_center(time_center_s, pseudo_period_s) sig_noise = white_noise_fbits(np.copy(sig_gt), noise_std_loss_bits) gt_white = sig_gt + sig_noise # AA filter gt_white_aa = antialias_halfNyquist(gt_white) return gt_white_aa
def gt_blast_center_fast( frequency_peak_hz: float = 6.3, sample_rate_hz: float = 100., noise_std_loss_bits: float = 16) -> Tuple[np.ndarray, np.ndarray]: """ Fast computation of GT pulse with noise :param frequency_peak_hz: peak frequency, nominal 6.3 Hz for 1 tonne TNT :param sample_rate_hz: sample rate, nominal 100 Hz :param noise_std_loss_bits: noise loss relative to signal variance :return: centered time in seconds, GT pulse with white noise """ duration_s = 16 / frequency_peak_hz # 16 cycles for 6th octave (M = 14) pseudo_period_s = 1 / frequency_peak_hz duration_points = int(duration_s * sample_rate_hz) time_center_s = np.arange(duration_points) / sample_rate_hz time_center_s -= time_center_s[-1] / 2. sig_gt = gt_blast_period_center(time_center_s, pseudo_period_s) sig_noise = white_noise_fbits(sig_gt, noise_std_loss_bits) gt_white = sig_gt + sig_noise # AA filter gt_white_aa = antialias_halfNyquist(gt_white) return time_center_s, gt_white_aa
sig_wf_red = np.concatenate( [np.zeros(head_points), sig_wf_red, np.zeros(head_points)]) sig_time_s = np.arange(len(sig_wf_red)) / sig_wf_sample_rate_hz sig_duration_s = np.max(sig_time_s) # Blueshift sig_wf_blue = np.flipud(sig_wf_red) # Choose origin and red/blue shift sig_wf_epoch_s = sig_time_s + run_time_epoch_s sig_wf = np.copy(np.imag(sig_wf_red)) # Antialias filter synthetic synthetics.antialias_halfNyquist(synth=sig_wf) # Export to wav directory if do_save_wave: wav_sample_rate_hz = 8000. export_filename = os.path.join(output_wav_directory, wav_filename + "_8kz.wav") synth_wav = 0.9 * np.real(sig_wf) / np.max(np.abs((np.real(sig_wf)))) scipy.io.wavfile.write(export_filename, int(wav_sample_rate_hz), synth_wav) # Frame to mic start and end and plot event_reference_time_epoch_s = sig_wf_epoch_s[0] # The min_frequency_hz is needed for STFT max_time_s, min_frequency_hz = scales.from_duration(
time_s = np.arange(time_points)/frequency_sample_rate_hz time_half_s = np.max(time_s)/2. time_shifted_s = time_s - time_half_s # Build signal, no noise sig_gt = kaboom.gt_blast_period_center(time_center_s=time_shifted_s, pseudo_period_s=pseudo_period_s) # Add white noise # Variance computed from transient, stressing at bit_loss=1 bit_loss = 6 sig_noise = synth.white_noise_fbits(sig=sig_gt, std_bit_loss=bit_loss) gt_white = sig_gt + sig_noise # AA filter of signal with noise sig_n = synth.antialias_halfNyquist(synth=gt_white) # With noise # Compute complex wavelet transform of real signal + noise cwtm, _, _, frequency_hz = \ atoms.cwt_chirp_from_sig(sig_wf=sig_n, frequency_sample_rate_hz=frequency_sample_rate_hz, band_order_Nth=order_Nth) # Reconstruction coefficients _, reconstruct = \ atoms_inverse.morlet2_reconstruct(band_order_Nth=order_Nth, scale_frequency_center_hz=frequency_hz, frequency_sample_rate_hz=frequency_sample_rate_hz) # Scaled wavelet coefficients f_x_cwtm = utils.d1tile_x_d2(d1=reconstruct, d2=cwtm.real) # Inverse to verify reconstruction (only works for real, returns Hilbert on imaginary
# Select signal sig_gt = kaboom.gt_blast_period_center(time_center_s=time_shifted_s, pseudo_period_s=pseudo_period_s) sig_gt_hilbert = kaboom.gt_hilbert_blast_period_center(time_center_s=time_shifted_s, pseudo_period_s=pseudo_period_s) sig_complex = sig_gt + sig_gt_hilbert*1j # Add white noise # Variance computed from transient bit_loss = 1 sig_noise = synth.white_noise_fbits(sig=sig_gt, std_bit_loss=bit_loss) gt_white = sig_gt + sig_noise gt_white_hilbert = sig_gt_hilbert + sig_noise # AA filter noise = synth.antialias_halfNyquist(synth=sig_noise) sig_n = synth.antialias_halfNyquist(synth=gt_white) sig_n_hilbert = synth.antialias_halfNyquist(synth=gt_white_hilbert) # Analytic record sig_n_complex = sig_n + sig_n_hilbert*1j # Compute complex wavelet transform cwtm, _, _, frequency_hz = \ atoms.cwt_chirp_from_sig(sig_wf=sig_n, frequency_sample_rate_hz=frequency_sample_rate_hz, band_order_Nth=order_Nth) # For noise cwtm_noise, _, _, _ = \ atoms.cwt_chirp_from_sig(sig_wf=noise, frequency_sample_rate_hz=frequency_sample_rate_hz, band_order_Nth=order_Nth)
order_number_input = 12 EVENT_NAME = "Tone Test" station_id_str = 'Synthya' run_time_epoch_s = utils.datetime_now_epoch_s() mic_sig_sample_rate_hz = 800. sig_frequency_hz = 50. sig_duration_s = 5. # Construct synthetic tone with max unit amplitude mic_sig_epoch_s = np.arange(int(mic_sig_sample_rate_hz * sig_duration_s)) / mic_sig_sample_rate_hz + run_time_epoch_s mic_sig = np.sin(2*np.pi*sig_frequency_hz*mic_sig_epoch_s) mic_sig += synthetics.white_noise_fbits(sig=mic_sig, std_bit_loss=4.) mic_sig *= utils.taper_tukey(mic_sig_epoch_s, fraction_cosine=0.1) # add taper synthetics.antialias_halfNyquist(mic_sig) # Antialias filter synthetic # Frame to mic start and end and plot event_reference_time_epoch_s = mic_sig_epoch_s[0] max_time_s, min_frequency_hz = scales.from_duration(band_order_Nth=order_number_input, sig_duration_s=sig_duration_s) print('\nRequest Order N=', order_number_input) print('Lowest frequency in hz that can support this order for this signal duration is ', min_frequency_hz) print('Scale with signal duration and to Nyquist, default G2 base re F1') # Select plot frequencies fmin = np.ceil(min_frequency_hz) fmax = 400 # TFR SECTION