def _shift_and_ifft(self, fdsinx, tshift, fseries=None): """Calls apply_fd_time_shift, and iFFTs to the time domain. """ start_time = self.time_series.start_time tdshift = apply_fd_time_shift(fdsinx, start_time+tshift, fseries=fseries) if not isinstance(tdshift, FrequencySeries): # cast to FrequencySeries so time series will work tdshift = FrequencySeries(tdshift, delta_f=fdsinx.delta_f, epoch=fdsinx.epoch) return tdshift.to_timeseries()
def _shift_and_ifft(self, fdsinx, tshift, fseries=None): """Calls apply_fd_time_shift, and iFFTs to the time domain. """ start_time = self.time_series.start_time tdshift = apply_fd_time_shift(fdsinx, start_time + tshift, fseries=fseries) if not isinstance(tdshift, FrequencySeries): # cast to FrequencySeries so time series will work tdshift = FrequencySeries(tdshift, delta_f=fdsinx.delta_f, epoch=fdsinx.epoch) return tdshift.to_timeseries()
def validate_waveform( waveform: np.ndarray, static_args: Dict[str, float], out_dir: Union[str, os.PathLike], name: Optional[str]=None, ): # create out dir if it does not exist out_dir = Path(out_dir) out_dir.mkdir(exist_ok=True) # Generate waveform assert waveform.shape[0] == 2, "First dimension of waveform sample must be 2 (+ and x polarizations)." assert waveform.shape[1] == static_args['fd_length'], "Waveform length not expected given provided static_args." hp, hc = waveform plus = FrequencySeries(hp, delta_f=static_args['delta_f'], copy=True) cross = FrequencySeries(hc, delta_f=static_args['delta_f'], copy=True) # ifft to time domain sp = plus.to_timeseries(delta_t=static_args['delta_t']) sc = cross.to_timeseries(delta_t=static_args['delta_t']) # plot plus / cross polarizations fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(16, 4)) ax.plot(sp.sample_times, sp, label='Plus', color='tab:pink') # pink for plus ax.plot(sc.sample_times, sc, label='Cross', color='tab:cyan') # cyan for cross ax.set_ylabel('Strain') ax.set_xlabel('Time (s)') ax.grid('both') aux_desc='' if name is None else f' ({name})' ax.set_title(f"IFFT of Simulated {static_args['approximant']} Waveform Polarizations{aux_desc}", fontsize=14) ax.legend(loc='upper left') fig.tight_layout() fig.savefig(out_dir / 'intrinsic_polarizations.png')
def validate_projections( projections: np.ndarray, static_args: Dict[str, float], out_dir: Optional[Union[str, os.PathLike]]=None, ifos: Optional[List[str]]=None, name: Optional[str]=None, save: bool=True, show: bool=False, ): # full names for plotting interferometers = {'H1': 'Hanford', 'L1': 'Livingston', 'V1': 'Virgo', 'K1': 'KAGRA'} # Generate waveform if ifos is not None: assert projections.shape[0] == len(ifos), "First dimension of waveform sample must be 2 (+ and x polarizations)." assert projections.shape[1] == static_args['fd_length'], "Waveform length not expected given provided static_args." nrows, ncols = 1, 1 fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=(16, 4*nrows)) # ifft to time domain for i in range(projections.shape[0]): label = None if ifos is None else interferometers[ifos[i]] h = FrequencySeries(projections[i, :], delta_f=static_args['delta_f'], copy=True) strain = h.to_timeseries(delta_t=static_args['delta_t']) ax.plot(strain.sample_times, strain, label=label, alpha=0.6) ax.set_ylabel('Strain') ax.set_xlabel('Time (s)') ax.grid('both') ax.legend(loc='upper left') aux_desc='' if name is None else f' ({name})' fig.suptitle(f"IFFT of Simulated {static_args['approximant']} Projected Waveforms at Interferometers{aux_desc}", fontsize=16) fig.tight_layout() if save: # create out dir if it does not exist out_dir = Path(out_dir) out_dir.mkdir(exist_ok=True) fig.savefig(out_dir / 'projection_examples.png') if show: fig.show()
def calculate_acf(data, delta_t=1.0, unbiased=False): """ Calculates the autocorrelation function (ACF) and returns the one-sided ACF. The ACF is defined as the autocovariance divided by the variance. The ACF can be estimated using \hat{R}(k) = \frac{1}{\left( n \sigma^{2}} \right) \sum_{t=1}^{n-k} \left( X_{t} - \mu \right) \left( X_{t+k} - \mu \right) Where \hat{R}(k) is the ACF, X_{t} is the data series at time t, \mu is the mean of X_{t}, and \sigma^{2} is the variance of X_{t}. Parameters ----------- data : {TimeSeries, numpy.array} A TimeSeries or numpy.array of data. delta_t : float The time step of the data series if it is not a TimeSeries instance. unbiased : bool If True the normalization of the autocovariance function is n-k instead of n. This is called the unbiased estimation of the autocovariance. Note that this does not mean the ACF is unbiased. Returns ------- acf : numpy.array If data is a TimeSeries then acf will be a TimeSeries of the one-sided ACF. Else acf is a numpy.array. """ # if given a TimeSeries instance then get numpy.array if isinstance(data, TimeSeries): y = data.numpy() delta_t = data.delta_t else: y = data # FFT data minus the mean fdata = TimeSeries(y-y.mean(), delta_t=delta_t).to_frequencyseries() # correlate # do not need to give the congjugate since correlate function does it cdata = FrequencySeries(zeros(len(fdata), dtype=numpy.complex64), delta_f=fdata.delta_f, copy=False) correlate(fdata, fdata, cdata) # IFFT correlated data to get unnormalized autocovariance time series acf = cdata.to_timeseries() # normalize the autocovariance # note that dividing by acf[0] is the same as ( y.var() * len(acf) ) if unbiased: acf /= ( y.var() * numpy.arange(len(acf), 0, -1) ) else: acf /= acf[0] # return input datatype if isinstance(data, TimeSeries): return TimeSeries(acf, delta_t=delta_t) else: return acf
def calculate_acf(data, delta_t=1.0, unbiased=False): r"""Calculates the one-sided autocorrelation function. Calculates the autocorrelation function (ACF) and returns the one-sided ACF. The ACF is defined as the autocovariance divided by the variance. The ACF can be estimated using .. math:: \hat{R}(k) = \frac{1}{n \sigma^{2}} \sum_{t=1}^{n-k} \left( X_{t} - \mu \right) \left( X_{t+k} - \mu \right) Where :math:`\hat{R}(k)` is the ACF, :math:`X_{t}` is the data series at time t, :math:`\mu` is the mean of :math:`X_{t}`, and :math:`\sigma^{2}` is the variance of :math:`X_{t}`. Parameters ----------- data : TimeSeries or numpy.array A TimeSeries or numpy.array of data. delta_t : float The time step of the data series if it is not a TimeSeries instance. unbiased : bool If True the normalization of the autocovariance function is n-k instead of n. This is called the unbiased estimation of the autocovariance. Note that this does not mean the ACF is unbiased. Returns ------- acf : numpy.array If data is a TimeSeries then acf will be a TimeSeries of the one-sided ACF. Else acf is a numpy.array. """ # if given a TimeSeries instance then get numpy.array if isinstance(data, TimeSeries): y = data.numpy() delta_t = data.delta_t else: y = data # Zero mean y = y - y.mean() ny_orig = len(y) npad = 1 while npad < 2*ny_orig: npad = npad << 1 ypad = numpy.zeros(npad) ypad[:ny_orig] = y # FFT data minus the mean fdata = TimeSeries(ypad, delta_t=delta_t).to_frequencyseries() # correlate # do not need to give the congjugate since correlate function does it cdata = FrequencySeries(zeros(len(fdata), dtype=numpy.complex64), delta_f=fdata.delta_f, copy=False) correlate(fdata, fdata, cdata) # IFFT correlated data to get unnormalized autocovariance time series acf = cdata.to_timeseries() acf = acf[:ny_orig] # normalize the autocovariance # note that dividing by acf[0] is the same as ( y.var() * len(acf) ) if unbiased: acf /= ( y.var() * numpy.arange(len(acf), 0, -1) ) else: acf /= acf[0] # return input datatype if isinstance(data, TimeSeries): return TimeSeries(acf, delta_t=delta_t) else: return acf
def calculate_acf(data, delta_t=1.0, unbiased=False): r"""Calculates the one-sided autocorrelation function. Calculates the autocorrelation function (ACF) and returns the one-sided ACF. The ACF is defined as the autocovariance divided by the variance. The ACF can be estimated using .. math:: \hat{R}(k) = \frac{1}{n \sigma^{2}} \sum_{t=1}^{n-k} \left( X_{t} - \mu \right) \left( X_{t+k} - \mu \right) Where :math:`\hat{R}(k)` is the ACF, :math:`X_{t}` is the data series at time t, :math:`\mu` is the mean of :math:`X_{t}`, and :math:`\sigma^{2}` is the variance of :math:`X_{t}`. Parameters ----------- data : TimeSeries or numpy.array A TimeSeries or numpy.array of data. delta_t : float The time step of the data series if it is not a TimeSeries instance. unbiased : bool If True the normalization of the autocovariance function is n-k instead of n. This is called the unbiased estimation of the autocovariance. Note that this does not mean the ACF is unbiased. Returns ------- acf : numpy.array If data is a TimeSeries then acf will be a TimeSeries of the one-sided ACF. Else acf is a numpy.array. """ # if given a TimeSeries instance then get numpy.array if isinstance(data, TimeSeries): y = data.numpy() delta_t = data.delta_t else: y = data # Zero mean y = y - y.mean() ny_orig = len(y) npad = 1 while npad < 2*ny_orig: npad = npad << 1 ypad = numpy.zeros(npad) ypad[:ny_orig] = y # FFT data minus the mean fdata = TimeSeries(ypad, delta_t=delta_t).to_frequencyseries() # correlate # do not need to give the congjugate since correlate function does it cdata = FrequencySeries(zeros(len(fdata), dtype=fdata.dtype), delta_f=fdata.delta_f, copy=False) correlate(fdata, fdata, cdata) # IFFT correlated data to get unnormalized autocovariance time series acf = cdata.to_timeseries() acf = acf[:ny_orig] # normalize the autocovariance # note that dividing by acf[0] is the same as ( y.var() * len(acf) ) if unbiased: acf /= ( y.var() * numpy.arange(len(acf), 0, -1) ) else: acf /= acf[0] # return input datatype if isinstance(data, TimeSeries): return TimeSeries(acf, delta_t=delta_t) else: return acf
delta_f=fp['{}/psds/0'.format(ifo)].attrs['delta_f'])\ /DYN_RANGE_FAC**2 asd = FrequencySeries(numpy.sqrt(psd.numpy()), delta_f=psd.delta_f) # get the strain print "loading strain" stilde = FrequencySeries( fp['{}/stilde'.format(ifo)][:], delta_f=fp['{}/stilde'.format(ifo)].attrs['delta_f'], epoch=fp['{}/stilde'.format(ifo)].attrs['epoch']) print "whitening" wh_stilde = FrequencySeries(stilde / asd, delta_f=stilde.delta_f, epoch=stilde.epoch) wh_strain = wh_stilde.to_timeseries() #load map values llrs = fp.read_likelihood_stats(iteration=opts.iteration, thin_start=opts.thin_start, thin_end=opts.thin_end, thin_interval=opts.thin_interval) map_idx = (llrs.loglr + llrs.prior).argmax() map_values = samples[map_idx] varargs = fp.variable_args sargs = fp.static_args print "generating injected waveforms" genclass = generator.select_waveform_generator( fp.static_args['approximant'])
def tensorboard_writer( queue: mp.Queue, log_dir: str, parameters: List[str], labels: List[str], static_args_ini: str, basis_dir: str, num_basis: int, val_coefficients: Optional[torch.Tensor] = None, val_gts: Optional[torch.Tensor] = None, figure_titles: Optional[List[str]] = None, ): # suppress luminosity distance debug messages logger = logging.getLogger('bilby') logger.propagate = False logger.setLevel(logging.WARNING) if log_dir is None: tb = SummaryWriter() else: tb = SummaryWriter(log_dir) _, static_args = read_ini_config(static_args_ini) ifos = ('H1', 'L1') interferometers = { 'H1': 'Hanford', 'L1': 'Livingston', 'V1': 'Virgo', 'K1': 'KAGRA' } basis_dir = Path(basis_dir) basis = SVDBasis(basis_dir, static_args_ini, ifos, file=None, preload=False) basis.load(time_translations=False, verbose=False) basis.truncate(num_basis) val_coefficients = val_coefficients.numpy() for j in range(val_coefficients.shape[0]): fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(16, 4)) for i, ifo in enumerate(ifos): Vh = basis.Vh[0] if basis.Vh.shape[0] == 1 else basis.Vh[i] reconstruction = val_coefficients[j, i] @ Vh reconstruction = FrequencySeries(reconstruction, delta_f=static_args['delta_f']) strain = reconstruction.to_timeseries( delta_t=static_args['delta_t']) ax.plot(strain.sample_times, strain, label=interferometers[ifo], alpha=0.6) ax.set_title(f'Reconstructed {figure_titles[j]} Strain') ax.set_xlabel('Time (s)') ax.set_ylabel('Strain') # units? ax.set_xlim((static_args['seconds_before_event'] - 1, static_args['seconds_before_event'] + 1)) ax.legend(loc='upper left') ax.grid('both') # ax.axvline(static_args['seconds_before_event'], color='r', linestyle='--') # merger time marker # ax.set_xticks([static_args['seconds_before_event']], minor=True) # add low frequency cutoff to ticks # ax.set_xticklabels(['$t_{c}$'], minor=True, color='r') tb.add_figure(f'reconstructions/{figure_titles[j]}', fig) del reconstruction del val_coefficients del basis # bilby setup - specify the output directory and the name of the bilby run result = bilby.result.read_in_result(outdir='bilby_runs/GW150914', label='GW150914') bilby_parameters = [ 'mass_1', 'mass_2', 'phase', 'geocent_time', 'luminosity_distance', 'a_1', 'a_2', 'tilt_1', 'tilt_2', 'phi_12', 'phi_jl', 'theta_jn', 'psi', 'ra', 'dec' ] bilby_samples = result.posterior[bilby_parameters].values # # Shift the time of coalescence by the trigger time bilby_samples[:, 3] = bilby_samples[:, 3] - Merger('GW150914').time bilby_df = pd.DataFrame(bilby_samples.astype(np.float32), columns=bilby_parameters) bilby_df = bilby_df.rename(columns={ 'luminosity_distance': 'distance', 'geocent_time': 'time' }) bilby_df = bilby_df.loc[:, parameters] domain = [ [10, 80], # mass 1 [10, 80], # mass 2 [0, 2 * np.pi], # phase [0, 1], # a_1 [0, 1], # a 2 [0, np.pi], # tilt 1 [0, np.pi], # tilt 2 [0, 2 * np.pi], # phi_12 [0, 2 * np.pi], # phi_jl [0, np.pi], # theta_jn [0, np.pi], # psi [0, 2 * np.pi], # ra [-np.pi / 2, np.pi / 2], # dec # [0.005,0.055], # tc [100, 800], # distance ] cosmoprior = bilby.gw.prior.UniformSourceFrame( name='luminosity_distance', minimum=1e2, maximum=1e3, ) while True: try: epoch, scalars, samples = queue.get() if samples is not None: # requires (batch, samples, parameters) assert len( samples.shape ) == 3, "samples must be of shape (batch, samples, parameters)" if figure_titles is not None: # to do - better handling of passing figure info through queue assert samples.shape[0] == len(figure_titles), ( "sample.shape[0] and figure_titles must have matching lengths" ) else: figure_titles = [''] * samples.shape[0] for key, value in scalars.items(): tb.add_scalar(key, value, epoch) if samples is not None: assert isinstance(samples, torch.Tensor) for i in range(samples.shape[0]): fig = plt.figure(figsize=(20, 21)) if i == 0: # GW150914 ONLY - hardcoded to first position samples_df = pd.DataFrame(samples[i].numpy(), columns=parameters) weights = cosmoprior.prob(samples_df['distance']) weights = weights / np.mean(weights) corner.corner( bilby_df, fig=fig, labels=labels, levels=[0.5, 0.9], quantiles=[0.25, 0.75], color='tab:orange', scale_hist=True, plot_datapoints=False, ) corner.corner( samples_df, fig=fig, levels=[0.5, 0.9], quantiles=[0.25, 0.75], color='tab:blue', scale_hist=True, plot_datapoints=False, show_titles=True, weights=weights * len(bilby_samples) / len(samples_df), range=domain, ) fig.legend( handles=[ mpatches.Patch(color='tab:blue', label='Neural Spline Flow'), mpatches.Patch(color='tab:orange', label='Bilby (dynesty)') ], loc='upper right', fontsize=16, ) else: samples_df = pd.DataFrame(samples[i].numpy(), columns=parameters) weights = cosmoprior.prob(samples_df['distance']) weights = weights / np.mean(weights) corner.corner( samples_df, fig=fig, labels=labels, levels=[0.5, 0.9], quantiles=[0.25, 0.75], color='tab:blue', truth_color='tab:orange', scale_hist=True, plot_datapoints=False, show_titles=True, truths=val_gts[i].numpy() if val_gts is not None else None, weights=weights * len(bilby_samples) / len(samples_df), range=domain, ) fig.legend( handles=[ mpatches.Patch(color='tab:blue', label='Neural Spline Flow'), mpatches.Patch(color='tab:orange', label='Ground Truth') ], loc='upper right', fontsize=16, ) fig.suptitle(f'{figure_titles[i]} Parameter Estimation', fontsize=18) # fig.savefig(f'gwpe/figures/{figure_titles[i]}.png') tb.add_figure(f'posteriors/{figure_titles[i]}', fig, epoch) tb.flush() except Exception as e: # warning: assertions may not trigger exception to exit process traceback.print_exc() os.kill(os.getpid(), signal.SIGSTOP) # to do: check kill command
m1 = m2 = 1.4 mchirp = float(pycbc.conversions.mchirp_from_mass1_mass2(m1, m2)) eta = float(pycbc.conversions.eta_from_mass1_mass2(m1, m2)) hp = numpy.zeros(flen, dtype=numpy.complex128) hc = hp.copy() f = lib.generate f.argtypes = [ c_void_p, c_void_p, c_double, c_double, c_double, c_double, c_double, c_double, c_double, c_double, c_double ] _ = f(hp.ctypes.data, hc.ctypes.data, mchirp, eta, inc, ecc, lamc, lc, dist, fend, df) import pylab # it appears that the plus / cross data is time inverted hp = FrequencySeries(hp.conj(), delta_f=df, epoch=-int(1.0 / df)) hc = FrequencySeries(hc.conj(), delta_f=df, epoch=-int(1.0 / df)) kmin = int(flow / df) hp[:kmin].clear() hc[:kmin].clear() t = hp.to_timeseries() pylab.plot(t.sample_times, t) #pylab.xscale('log') pylab.show()