def make_inspiral_merger_plot( hp1, hc1, hp2, hc2, tscale=1., lp=0.9, rp=1.1,\ xlabel='$\mathrm{Time (M)}$', ylabel='$\\frac{R}{M}\,h_{22}\,(t)$',\ legend=None, savefig='plot.pdf'): a1 = amplitude_from_polarizations(hp1, hc1) _, max_id1 = a1.abs_max_loc() a2 = amplitude_from_polarizations(hp2, hc2) _, max_id2 = a2.abs_max_loc() # # plot it fig = plt.figure(figsize=(8 / 2, 8 / golden_ratio / 2)) gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1]) ax0 = plt.subplot(gs[0]) ax0.plot(np.arange(len(hp1))*tscale, hp1, np.arange(len(hp2))*tscale, hp2,\ lw=0.5 ) xmin, xmax = 0, min(max_id1, max_id2) * lp * tscale ax0.set_xlim(xmin, xmax) ax0.set_xlabel(xlabel) ax0.set_ylabel(ylabel) ax0.legend(legend, loc='best') # ax1 = plt.subplot(gs[1]) ax1.plot(np.arange(len(hp1))*tscale, hp1, np.arange(len(hp2))*tscale, hp2,\ lw=0.5) xmin, xmax = min(max_id1, max_id2) * lp * tscale, min( max_id1, max_id2) * rp * tscale ax1.set_xlim(xmin, xmax) print xmin, xmax ax1.set_xticks([int(xmin*0.9 + 0.1*xmax),\ int(xmin*0.5+0.5*xmax),\ int(xmin*0.05+0.95*xmax)]) # plt.tight_layout() plt.savefig(savefig)
def align_waveforms_amplitude_peak(hplus1, hcross1, hplus2, hcross2): # # Find amplitude peaks # hp1, hc1 = TimeSeries(hplus1), TimeSeries(hcross1) hp2, hc2 = TimeSeries(hplus2), TimeSeries(hcross2) amp1 = amplitude_from_polarizations(hp1, hc1) amp2 = amplitude_from_polarizations(hp2, hc2) # Get amplitude peaks amp1I = interp1d(amp1.sample_times, -1 * amp1.data) x0 = np.float64( np.where(amp1.data == max(amp1.data))[0][0] * amp1.delta_t + amp1._epoch) tmp = minimize_scalar(amp1I, x0, method='bounded', bounds=(x0 - 10 * amp1.delta_t, x0 + 10 * amp1.delta_t)) h1_max_amp_time = tmp['x'] h1_max_amp = -1 * tmp['fun'] amp2I = interp1d(amp2.sample_times, -1 * amp2.data) x0 = np.float64( np.where(amp2.data == max(amp2.data))[0][0] * amp2.delta_t + amp2._epoch) tmp = minimize_scalar(amp2I, x0, method='bounded', bounds=(x0 - 10 * amp2.delta_t, x0 + 10 * amp2.delta_t)) h2_max_amp_time = tmp['x'] h2_max_amp = -1 * tmp['fun'] print("h1 max time = %f, epoch = %f" % (h1_max_amp_time, float(hp1._epoch))) print("h2 max time = %f, epoch = %f" % (h2_max_amp_time, float(hp2._epoch))) # Amplitude location from the start t1 = np.float64(h1_max_amp_time - hp1._epoch) t2 = np.float64(h2_max_amp_time - hp2._epoch) t_shift = t1 - t2 print("time shift = %f" % t_shift) # # Find phase shift # phs1 = phase_from_polarizations(hp1, hc1) phs2 = phase_from_polarizations(hp2, hc2) ph1 = phs1[int(np.round(t1 / hp1.delta_t))] ph2 = phs2[int(np.round(t2 / hp2.delta_t))] print("phase1 at peak idx = %d, = %f" % (int(np.round(t1 / hp1.delta_t)), ph1)) print("phase2 at peak idx = %d, = %f" % (int(np.round(t2 / hp2.delta_t)), ph2)) ph_shift = (ph1 - ph2) * 1 print("phase shift = %f" % ph_shift) # # Enforced that phase at merger be 0 for BOTH hp1, hc1 = shift_waveform_phase_time(hp1, hc1, 0, -0 - 1. * ph1) hp2, hc2 = shift_waveform_phase_time(hp2, hc2, t_shift, -0 - 1. * ph2) # return hp1, hc1, hp2, hc2
def get_ncycles_to_merger(hp, hc): if type(hp) == FrequencySeries: return -1 a = amplitude_from_polarizations(hp, hc) p = phase_from_polarizations(hp, hc) idx = a.abs_max_loc()[-1] ncyc = np.abs(p[idx] - p[0]) / np.pi / 2.0 return ncyc
def shift_waveform_phase_time(hp, hc, t_shift, ph_shift): hpnew = TimeSeries(hp, epoch=hp._epoch, delta_t=hp.delta_t, dtype=hp.dtype) hcnew = TimeSeries(hc, epoch=hc._epoch, delta_t=hc.delta_t, dtype=hc.dtype) # Now apply phase shift if ph_shift != 0.: amplitude = amplitude_from_polarizations(hpnew, hc) phase = phase_from_polarizations(hpnew, hc) print("shifting by %f radians" % ph_shift) phase = phase + ph_shift hpnew = TimeSeries(amplitude * np.cos(phase), epoch=hpnew._epoch, delta_t=hpnew.delta_t, dtype=hpnew.dtype) hcnew = TimeSeries(-1 * amplitude * np.sin(phase), epoch=hcnew._epoch, delta_t=hcnew.delta_t, dtype=hcnew.dtype) # First apply time shift print("shifting by %e secs" % t_shift) if t_shift != 0: idx_shift = int(np.round(t_shift / hpnew.delta_t)) hpnew.roll(idx_shift) hcnew.roll(idx_shift) #hpnew._epoch = hpnew._epoch + t_shift #hcnew._epoch = hcnew._epoch + t_shift return hpnew, hcnew
def write_raw_modes_to_ASCII(waves, subsamp_n=1, modes=True): """ Write mode time-series to disk as ASCII. Very specific inputs. """ # {{{ for file_name, mode_array, splines, tminmax in waves.values(): # Header header_string = "[1] Time" for jdx, mode_lm in enumerate(mode_array): el, em = mode_lm spline_real, spline_imag = splines[jdx] if modes: header_string += "\n[%d] Re[h%d%d]" % (2 * jdx + 2, el, em) header_string += "\n[%d] Im[h%d%d]" % (2 * jdx + 3, el, em) else: # If compression was not desired, check if raw amp/phase are to # be written instead of the raw modes ampLM = amplitude_from_polarizations(spline_real, spline_imag) phsLM = phase_from_polarizations(spline_real, spline_imag) + np.pi spline_real, spline_imag = ampLM, phsLM header_string += "\n[%d] Amp[h%d%d]" % (2 * jdx + 2, el, em) header_string += "\n[%d] Phase[h%d%d]" % (2 * jdx + 3, el, em) # if jdx == 0: data_array = np.array( list( zip(spline_real.sample_times.data, spline_real.data, spline_imag.data))) elif jdx > 0: tmp_data_array = np.array( list(zip(spline_real.data, spline_imag.data))) data_array = np.append(data_array, tmp_data_array, axis=1) # Downsample data data_array = data_array[::subsamp_n, :] ## # Write to file ## nrow, ncol = np.shape(data_array) file_format = '' for j in range(ncol): file_format += '%.16e\t' # Write if not os.path.exists(file_name): np.savetxt(file_name + '.txt.gz', data_array, fmt=file_format, header=header_string) else: print("Warning: FILE NOT WRITTEN FOR ", file_name, header_string) continue return
def write_raw_modes_to_HDF5(waves, subsamp_n=1, modes=True): """ Write mode time-series to disk as ASCII. Very specific inputs. """ # {{{ for file_name, mode_array, splines, tminmax in waves.values(): # Write data to HDF5 file by passing a group descriptor fp = h5py.File(file_name + '.h5', 'w') # Header header_string = "[1] Time" for jdx, mode_lm in enumerate(mode_array): el, em = mode_lm spline_real, spline_imag = splines[jdx] if modes: header_string += "\n[%d] Re[h%d%d]" % (2 * jdx + 2, el, em) header_string += "\n[%d] Im[h%d%d]" % (2 * jdx + 3, el, em) else: # If compression was not desired, check if raw amp/phase are to # be written instead of the raw modes ampLM = amplitude_from_polarizations(spline_real, spline_imag) phsLM = phase_from_polarizations(spline_real, spline_imag) + np.pi spline_real, spline_imag = ampLM, phsLM header_string += "\n[%d] Amp[h%d%d]" % (2 * jdx + 2, el, em) header_string += "\n[%d] Phase[h%d%d]" % (2 * jdx + 3, el, em) # if jdx == 0: data_array = np.array( list( zip(spline_real.sample_times.data, spline_real.data, spline_imag.data))) elif jdx > 0: tmp_data_array = np.array( list(zip(spline_real.data, spline_imag.data))) data_array = np.append(data_array, tmp_data_array, axis=1) # Downsample data data_array = data_array[::subsamp_n, :] fp.create_dataset("AllModes", data=data_array) fp.create_dataset("TimeRangeInSeconds", data=tminmax) fp.create_dataset("ModesKey", data=header_string) fp.close() return
def gen_waveform(iota, phi, numrel_data): print "I am in gen_waveform()!" ## FIXME(Gonghan): It seems that this variable is never used. global wavelabel wavelabel = os.path.join(savepath, numrel_data.split('/')[-1].replace(".h5", "")) f = h5py.File(numrel_data, 'r') global hp, hc hp, hc = get_td_waveform(approximant='NR_hdf5', numrel_data=numrel_data, mass1=f.attrs['mass1'] * mass, mass2=f.attrs['mass2'] * mass, spin1z=f.attrs['spin1z'], spin2z=f.attrs['spin2z'], delta_t=1.0 / sample_frequency, f_lower=30., inclination=iota, coa_phase=phi, distance=1000) print "in gen_waveform, have got hp, hc. iota: {}, phi: {}".format( iota, phi) print "hp:", hp print "hc:", hc f.close() # Taper waveform for smooth FFTs hp = taper_timeseries(hp, tapermethod="TAPER_START") hc = taper_timeseries(hc, tapermethod="TAPER_START") global amp, foft amp = wfutils.amplitude_from_polarizations(hp, hc) foft = wfutils.frequency_from_polarizations(hp, hc) # Shift time origin to merger global sample_times ## FIXME(Gonghan): Not sure how we want to define zero time. sample_times = amp.sample_times - amp.sample_times[np.argmax(amp)]
if (row.snr > args.omicron_snr_thresh and omicron_start_time < row.peak_time < omicron_end_time): omicron_times.append(row.peak_time + row.peak_time_ns * 10**(-9)) omicron_snr.append(row.snr) omicron_freq.append(row.peak_frequency) # Generate inspiral waveform and calculate f(t) to plot on top of Omicron triggers hp, hc = get_td_waveform(approximant='SEOBNRv2', mass1=m1, mass2=m2, spin1x=0, spin1y=0, spin1z=s1z, spin2x=0, spin2y=0, spin2z=s2z, delta_t=(1./32768.), f_lower=30) f = frequency_from_polarizations(hp, hc) amp = amplitude_from_polarizations(hp, hc) stop_idx = amp.abs_max_loc()[1] f = f[:stop_idx] freq = np.array(f.data) times = np.array(f.sample_times) + cbc_end_time logging.info('Plotting') plt.figure(0) cm = plt.cm.get_cmap('Reds') plt.scatter(omicron_times,omicron_freq,c=omicron_snr,s=30,cmap=cm,linewidth=0) plt.grid(b=True, which='both') cbar = plt.colorbar() cbar.set_label('%s Omicron trigger SNR' % (args.ifo))
# Generate inspiral waveform and calculate f(t) to plot on top of Omicron triggers hp, hc = get_td_waveform(approximant='SEOBNRv2', mass1=m1, mass2=m2, spin1x=0, spin1y=0, spin1z=s1z, spin2x=0, spin2y=0, spin2z=s2z, delta_t=(1. / 32768.), f_lower=30) f = frequency_from_polarizations(hp, hc) amp = amplitude_from_polarizations(hp, hc) stop_idx = amp.abs_max_loc()[1] f = f[:stop_idx] freq = np.array(f.data) times = np.array(f.sample_times) + cbc_end_time logging.info('Plotting') plt.figure(0) cm = plt.cm.get_cmap('Reds') plt.scatter(omicron_times, omicron_freq, c=omicron_snr, s=30,
def get_hplus_hcross_from_sxs(hdf5_file_name, template_params, delta_t,\ modeLmin = 2, modeLmax = 8, modeMmin = 2, modeMmax = None, junk_duration=600,\ taper=True, verbose=False, debug=False): if verbose: print(" \n\n\nIn get_hplus_hcross_from_sxs..", file=sys.stdout) sys.stdout.flush() # def get_param(value): try: if value == 'end_time': # FIXME: Imprecise! return float(template_params.get_end()) else: return getattr(template_params, value) except: return template_params[value] # # Get relevant binary parameters # total_mass = get_param('mtotal') theta = get_param('inclination') try: phi = get_param('coa_phase') except: phi = 0 distance = get_param('distance') end_time = get_param('end_time') # FIXME f_lower = get_param('f_lower') try: taper = get_param('taper') except: pass try: verbose = get_param('verbose') except: pass if debug: print("mass = {}, theta = {}, phi = {}, distance = {}, end_time = {}".format(\ total_mass, theta, phi, distance, end_time), file=sys.stdout) try: print("end_time = 0 (could be %f)" % template_params['end_time'], file=sys.stdout) except: pass # # Figure out how much memory to allocate # estimated_length_pow2 = nextpow2(MAX_NR_LENGTH * total_mass * lal.MTSUN_SI) if debug: print("estimated length = ", estimated_length_pow2) ########################################################################### # Read in the waveform from file & rescale it ########################################################################### if type(hdf5_file_name) != str: if verbose: print("\tUsing nr_wave datastructure. Rescaling to {}Msun".format( total_mass)) nrwav = hdf5_file_name nrwav.get_polarizations(M=total_mass, distance=distance, inclination=theta, phi=phi) if verbose: print("\tRescaled to {} Msun".format(nrwav.totalmass)) else: if verbose: print("\tReading in waveform from {}..".format(hdf5_file_name)) idx = 0 max_num_length_tries = 10 num_length_tries = max_num_length_tries while True: # this loop is to make sure that an under-estimation of the waveform's # length does not lead to failure, and we scale up the length allocation # till the whole NR waveform fits in it (in powers of 2) try: if debug: print("\n \t>>try %d at reading waveform" % (idx + 1)) print( "\t[More than ONE try is required if estimated NR length is too short]" ) idx += 1 group_name = get_param("group_name") # GROUP NAME nrwav = UseNRinDA.nr_wave(filename=hdf5_file_name, sample_rate=1./delta_t, time_length=estimated_length_pow2, \ totalmass=total_mass, inclination=theta, phi=phi, \ modeLmin=modeLmin, modeLmax=modeLmax,\ distance=distance*1e6,\ group_name=group_name,\ verbose=debug) break except ValueError as ve: estimated_length_pow2 *= 2 num_length_tries -= 1 if num_length_tries == 0: if verbose: print( "......................................................................" ) print("Max number of length retries exceeded: {}. Final length tried: {}".format(\ max_num_length_tries, estimated_length_pow2/2)) print("Final ERROR: {}".format(ve)) print( "......................................................................" ) break if debug and type(hdf5_file_name) == str: print("\t Waveform read from %s" % hdf5_file_name, file=sys.stdout) sys.stdout.flush() ########################################################################### ## Condition the waveform ## This is done with a Planck taper window which smoothly joins the start ## and the end of the waveform to zero. The width of such a window was ## investigated in Chu, Fong, Kumar et al (2015). We hard-code their ## pre-set tapering configuration. ## ## If conditioning is refused, returned waveform starts at exactly f_lower ## If conditioning is done, returned waveform starts at the start of taper ## window, which ends at f_lower ########################################################################### if verbose: print("Pre-conditioning waveform..") # Conditioning settings from Chu et al (2015) upwin_t_width = 1000 downwin_amp_frac = 0.01 downwin_t_width = 50 # 1) Check if re-scaling to input total mass is allowed by tapering # .. f_lower will be at least "junk_duration" away from the start if taper: t_filter = 0 + upwin_t_width else: t_filter = junk_duration m_lower = nrwav.get_lowest_binary_mass(t_filter, f_lower, totalmass=total_mass) if m_lower > total_mass: raise IOError("Cannot rescale below %f Msun starting at %fHz, asked for %f Msun" % \ (m_lower, f_lower, total_mass)) else: if verbose: print("Can comfortably rescale to %f Msun starting at %fHz" % (\ total_mass, f_lower)) # >> At this point, we know that f_lower is attained at t_filter or LATER # 2) Get the starting point of the waveform, given f_lower t_start_secs = nrwav.get_t_frequency(f_lower, totalmass=total_mass) t_start_secs -= float(nrwav.rescaled_hp._epoch) t_start_M = t_start_secs / (total_mass * lal.MTSUN_SI) t_start_index = int(np.round(t_start_secs / delta_t)) if debug: print("t_start_secs = %.2f" % t_start_secs) print("t_start_M = %.2f" % t_start_M) print("t_start_index= %d" % t_start_index) # # 3) Taper the waveform polarizations if taper: t_filter = t_start_M upwin_t_start = np.maximum(0., t_start_M - upwin_t_width) if upwin_t_width + upwin_t_start < junk_duration: if verbose > 0: print( "Tapering window was not covering junk radiation. Changing it to [0,{}}]" .format(junk_duration)) upwin_t_start = 0.0 upwin_t_width = junk_duration # if verbose: print("Length of waveform: ", (len(nrwav.rescaled_hp) * nrwav.delta_t / total_mass / lal.MTSUN_SI)) hp, hc = nrwav.taper_filter_waveform(ttaper1=upwin_t_start,\ ttaper2=upwin_t_width,\ ftaper3=downwin_amp_frac,\ ttaper4=downwin_t_width) # # Upgrade the index before which we trim the wave t_start_index = int( np.round(upwin_t_start / (hp.delta_t / total_mass / lal.MTSUN_SI))) if debug: print("Tapering window [start1-2], [end-amplfraction - t-width]: [%.1f - %.1f], [%.5f - %.1f]" %\ (upwin_t_start, upwin_t_width+upwin_t_start, downwin_amp_frac, downwin_t_width)) else: hp, hc = [nrwav.rescaled_hp, nrwav.rescaled_hc] if debug: print("Length of wave = %d" % len(hp), type(hp), type(hc)) print("t_start_index= %d" % t_start_index) # 4) Remove the part before f_lower / before start of tapering window hp = hp[t_start_index:] hc = hc[t_start_index:] # # 5) Chop off trailing zeros in the waveform. These include zeros at the # END of the waveform ONLY. The START does NOT change. if verbose: print("Post-process waveform vector..") #i_filter = int(np.ceil( t_filter * total_mass * lal.MTSUN_SI / nrwav.delta_t )) #hpExtraIdx = where(hp.data[i_filter:] == 0)[0] #hcExtraIdx = where(hc.data[i_filter:] == 0)[0] #idx = i_filter + hpExtraIdx[where(hpExtraIdx == hcExtraIdx)[0][0]] # #if debug: # print >>sys.stdout, " \tIndex = %d where waveform ends" % idx # print "\t Length of waveform BEFORE removing zeros = %d, %d" % (len(hp),len(hc)) # sys.stdout.flush() # Actually remove the trailing zeros hp = trim_trailing_zeros(hp) #hp[:idx] hc = trim_trailing_zeros(hc) #hc[:idx] if debug: print("\t Length of waveform AFTER removing zeros = %d, %d" % (len(hp), len(hc))) # # 6) Find the time at which the (2,2) mode's amplitude peaks, and use it to # set the epoch of the waveform being returned. Because trailing zeros have # been chopped off, that might alter the length of the simulation, # including spare zeros at the beginning. Therefore, we get the peak # amplitude AFTER this trimming. time_start_s = -1 * nrwav.get_amplitude_peak_h22( amplitude_from_polarizations(hp, hc))[-1] * nrwav.delta_t if debug: print(" \t time_start_s = %f" % time_start_s, file=sys.stdout) sys.stdout.flush() # # Prepare the output polarization vectors, with the correct epoch set # hp = TimeSeries(hp.data, delta_t=delta_t,\ epoch=lal.LIGOTimeGPS(end_time+time_start_s), copy=True) hc = TimeSeries(hc.data, delta_t=delta_t,\ epoch=lal.LIGOTimeGPS(end_time+time_start_s), copy=True) # if debug: for idx in range(len(hp) - 1, 1, -1): if hp[idx] != 0 and hc[idx] != 0: break try: print(" Length of rescaled waveform = %f.." % idx * hp.delta_t, file=sys.stdout) print(" hp.epoch = ", hp._epoch, file=sys.stdout) sys.stdout.flush() except: print(type(idx), type(hp)) # if debug: print("Returning hp, hc") # return hp, hc, nrwav
def compress_modes_to_splines(hLM, total_mass, to_amp_phase=True, to_modes=False, tol_one=1e-5, tol_two=1e-5, func_one=np.array, subsamp_fac_one_low=4, subsamp_fac_one_high=2, func_two=np.log, subsamp_fac_two_low=4, subsamp_fac_two_high=1, verbose=False): """ Compresses modes provided in hLM according to total mass, by either first converting to amplitude and phase OR using the modes directly. Users can subsample the time-series and apply a function to them before using romspline compression. These functions can decrease run time drastically. [DEFAULTS are sensible for raw modes.] """ # {{{ ################################# t_arr = TimeSeries(hLM.tdata.data * total_mass * lal.MTSUN_SI, delta_t=hLM.mode.deltaT) h_real = TimeSeries(hLM.mode.data.data.real, delta_t=hLM.mode.deltaT) h_imag = TimeSeries(hLM.mode.data.data.imag, delta_t=hLM.mode.deltaT) ampLM = amplitude_from_polarizations(h_real, h_imag) val, idx = ampLM.abs_max_loc() ################################# if to_amp_phase and not to_modes: if verbose: print("Converting to amplitude and phase") ################################# if verbose: __t0 = time.time() phsLM = phase_from_polarizations(h_real, h_imag) + np.pi phsLM_min = phsLM.min() ################# t_amp_subsampled = np.append( t_arr.data[0:idx - 500:subsamp_fac_one_low], t_arr.data[idx - 500:-1:subsamp_fac_one_high]) amp_subsampled = np.append( ampLM.data[0:idx - 500:subsamp_fac_one_low], ampLM.data[idx - 500:-1:subsamp_fac_one_high]) funcamp = func_one(amp_subsampled) # if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) __t0 = time.time() print("RomSpline compressing amplitude") funcamp_subsampled_spline = romspline.ReducedOrderSpline( t_amp_subsampled, funcamp, tol=tol_one) ################# t_phs_subsampled = np.append( t_arr.data[0:idx - 500:subsamp_fac_two_low], t_arr.data[idx - 500:-1:subsamp_fac_two_high]) phs_subsampled = np.append( phsLM.data[0:idx - 500:subsamp_fac_two_low], phsLM.data[idx - 500:-1:subsamp_fac_two_high]) funcphs = func_two(phs_subsampled - phsLM_min) # if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) __t0 = time.time() print("RomSpline compressing phase") # funcphs_subsampled_spline = romspline.ReducedOrderSpline( t_phs_subsampled, funcphs, tol=tol_two) if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) ################ return funcamp_subsampled_spline, funcphs_subsampled_spline, phsLM_min,\ t_arr.min(), t_arr.max() ################################# elif to_modes and not to_amp_phase: if verbose: print("Using mode real/imaginary parts directly") ################################# if verbose: __t0 = time.time() t_h_real_subsampled = np.append( t_arr.data[0:idx - 500:subsamp_fac_one_low], t_arr.data[idx - 500:-1:subsamp_fac_one_high]) h_real_subsampled = np.append( h_real.data[0:idx - 500:subsamp_fac_one_low], h_real.data[idx - 500:-1:subsamp_fac_one_high]) if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) __t0 = time.time() print("RomSpline compressing real part of mode") func_hreal_subsampled_spline = romspline.ReducedOrderSpline( t_h_real_subsampled, h_real_subsampled, tol=tol_one) # t_h_imag_subsampled = np.append( t_arr.data[0:idx - 500:subsamp_fac_two_low], t_arr.data[idx - 500:-1:subsamp_fac_two_high]) h_imag_subsampled = np.append( h_imag.data[0:idx - 500:subsamp_fac_two_low], h_imag.data[idx - 500:-1:subsamp_fac_two_high]) if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) __t0 = time.time() print("RomSpline compressing imaginary part of mode") func_himag_subsampled_spline = romspline.ReducedOrderSpline( t_h_imag_subsampled, h_imag_subsampled, tol=tol_two) if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) # return func_hreal_subsampled_spline, func_himag_subsampled_spline,\ t_arr.min(), t_arr.max() ################################# elif not to_modes and not to_amp_phase: if verbose: print("Using mode real/imaginary parts RAW (NOT COMPRESSING)") ################################# if verbose: __t0 = time.time() if verbose: print(" took %.2f seconds.." % (time.time() - __t0)) # return h_real, h_imag, t_arr.min(), t_arr.max() ################################# else: IOError( "CANNOT compress BOTH of amp/phase OR modes (CAN WRITE RAW though)" )
def shift_waveform_phase_time(hp, hc, t_shift, ph_shift, shift_epochs_only=True, trim_leading=False, trim_trailing=True, verbose=False): """ Input: hp, hc, where h = hp(t) + i hx(t) = Amp(t) * exp(-i * Phi(t)) Output: hp, hc, where h = Amp(t - t_c) * exp( -i * [Phi(t - t_c) + phi_c] ) """ hpnew = TimeSeries(hp, epoch=hp._epoch, delta_t=hp.delta_t, dtype=hp.dtype, copy=True) hcnew = TimeSeries(hc, epoch=hc._epoch, delta_t=hc.delta_t, dtype=hc.dtype, copy=True) # First apply phase shift if ph_shift != 0.: amplitude = amplitude_from_polarizations(hpnew, hcnew) phase = phase_from_polarizations(hpnew, hcnew) if verbose: print(("shifting by %f radians" % ph_shift)) phase = phase + ph_shift hpnew = TimeSeries(amplitude * np.cos(phase + np.pi), epoch=hpnew._epoch, delta_t=hpnew.delta_t, dtype=hpnew.dtype) hcnew = TimeSeries(amplitude * np.sin(phase + np.pi), epoch=hcnew._epoch, delta_t=hcnew.delta_t, dtype=hcnew.dtype) # Now apply time shift # Only positive time shifts can be applied by rolling forward data # if negative time shifts are asked for, we can only shift epochs if shift_epochs_only or t_shift <= 0: hpnew._epoch += t_shift hcnew._epoch += t_shift else: hpnewI = InterpolatedUnivariateSpline(hpnew.get_sample_times(), hpnew.data) hcnewI = InterpolatedUnivariateSpline(hcnew.get_sample_times(), hcnew.data) time_vals = hpnew.get_sample_times() shifted_time_vals = np.arange( time_vals[0], # start of new timeseries time_vals[-1] + t_shift + 0 * hpnew.delta_t, # end of it hpnew.delta_t) mask_times_to_reevaluate = [ (shifted_time_vals - t_shift >= time_vals[0]) & (shifted_time_vals - t_shift <= time_vals[-1]) ] hp_shifted = np.zeros(len(shifted_time_vals)) hp_shifted[mask_times_to_reevaluate] = hpnewI( shifted_time_vals[mask_times_to_reevaluate] - t_shift) hpnew = TimeSeries(hp_shifted, epoch=hpnew._epoch + t_shift, delta_t=hpnew.delta_t) hc_shifted = np.zeros(len(shifted_time_vals)) hc_shifted[mask_times_to_reevaluate] = hcnewI( shifted_time_vals[mask_times_to_reevaluate] - t_shift) hcnew = TimeSeries(hc_shifted, epoch=hcnew._epoch + t_shift, delta_t=hcnew.delta_t) if trim_trailing: hpnew = trim_trailing_zeros(hpnew) hcnew = trim_trailing_zeros(hcnew) if trim_leading: hpnew = trim_leading_zeros(hpnew) hcnew = trim_leading_zeros(hcnew) return hpnew, hcnew
def align_waveforms_amplitude_peak(hplus1, hcross1, hplus2, hcross2, shift_epochs_only=True, trim_leading=False, trim_trailing=True, verbose=False): """ Align the two waveforms, shifting only one of the two. - AT the Amplitude PEAK """ _dt = 1.0 if type(hplus1) == TimeSeries: _dt = hplus1.delta_t elif type(hplus2) == TimeSeries: _dt = hplus2.delta_t if type(hcross1) != TimeSeries: _dt = hcross1.delta_t if type(hcross2) != TimeSeries: _dt = hcross2.delta_t hp1 = TimeSeries(hplus1, delta_t=_dt, copy=True) hc1 = TimeSeries(hcross1, delta_t=_dt, copy=True) hp2 = TimeSeries(hplus2, delta_t=_dt, copy=True) hc2 = TimeSeries(hcross2, delta_t=_dt, copy=True) # Get amplitude peak for 1st set of polarizations amp1 = amplitude_from_polarizations(hp1, hc1) amp1I = InterpolatedUnivariateSpline(amp1.sample_times, -1 * amp1.data) x0 = np.float64( amp1.sample_times[np.where(amp1.data == max(amp1.data))[0][0]]) tmp = minimize_scalar(amp1I, x0, method='bounded', bounds=(x0 - 10 * amp1.delta_t, x0 + 10 * amp1.delta_t)) h1_max_amp_time = tmp['x'] h1_max_amp = -1 * tmp['fun'] # Get amplitude peak for 1st set of polarizations amp2 = amplitude_from_polarizations(hp2, hc2) amp2I = InterpolatedUnivariateSpline(amp2.sample_times, -1 * amp2.data) x0 = np.float64( amp2.sample_times[(np.where(amp2.data == max(amp2.data))[0][0])]) tmp = minimize_scalar(amp2I, x0, method='bounded', bounds=(x0 - 10 * amp2.delta_t, x0 + 10 * amp2.delta_t)) h2_max_amp_time = tmp['x'] h2_max_amp = -1 * tmp['fun'] if verbose: print(("h1 max time = %f, epoch = %f" % (h1_max_amp_time, float(hp1._epoch)))) print(("h2 max time = %f, epoch = %f" % (h2_max_amp_time, float(hp2._epoch)))) # Amplitude location from the start t1 = h1_max_amp_time t2 = h2_max_amp_time t_shift = t1 - t2 if verbose: print(("time shift = %f to be added to waveform 2" % t_shift)) # Find phase shift phs1 = phase_from_polarizations(hp1, hc1) phs2 = phase_from_polarizations(hp2, hc2) phs1I = InterpolatedUnivariateSpline(phs1.sample_times, phs1.data) phs2I = InterpolatedUnivariateSpline(phs2.sample_times, phs2.data) ph1 = phs1I(h1_max_amp_time) ph2 = phs2I(h2_max_amp_time) ph_shift = np.float64(ph1 - ph2) if verbose: print(("phase1 at peak idx = %d, = %f" % (int(np.round(t1 / hp1.delta_t)), ph1))) print(("phase2 at peak idx = %d, = %f" % (int(np.round(t2 / hp2.delta_t)), ph2))) print(("phase shift = %f, time shift = %f" % (ph_shift, t_shift))) # # Shift whichever needs to be shifted to future time. # Shifting back in time is tricky. if shift_epochs_only: hp2, hc2 = shift_waveform_phase_time(hp2, hc2, t_shift, ph_shift, shift_epochs_only=True, verbose=verbose) # Finally, shift everything's peak to t=0 hp1._epoch -= h1_max_amp_time hc1._epoch -= h1_max_amp_time hp2._epoch -= h1_max_amp_time hc2._epoch -= h1_max_amp_time # Trim leading zeros. If time shifts are actual shifts of data along the # array, the leading zeros have meaning and cannot be trimmed. if trim_leading and shift_epochs_only: hp1 = trim_leading_zeros(hp1) hc1 = trim_leading_zeros(hc1) hp2 = trim_leading_zeros(hp2) hc2 = trim_leading_zeros(hc2) else: t_shift += (amp2.sample_times[0] - amp1.sample_times[0]) if verbose: print("phase shift is actually = {}, time shift = {}".format( ph_shift, t_shift)) if t_shift >= 0: hp2, hc2 = shift_waveform_phase_time(hp2, hc2, t_shift, ph_shift, shift_epochs_only=False, verbose=verbose) hp1._epoch -= h1_max_amp_time hc1._epoch -= h1_max_amp_time hp2._epoch = hp1._epoch hc2._epoch = hc1._epoch else: hp1, hc1 = shift_waveform_phase_time(hp1, hc1, -1 * t_shift, ph_shift, shift_epochs_only=False, verbose=verbose) hp2._epoch -= h2_max_amp_time hc2._epoch -= h2_max_amp_time hp1._epoch = hp2._epoch hc1._epoch = hc2._epoch # Trim any trailing zeros if trim_trailing: hp1 = trim_trailing_zeros(hp1) hc1 = trim_trailing_zeros(hc1) hp2 = trim_trailing_zeros(hp2) hc2 = trim_trailing_zeros(hc2) return hp1, hc1, hp2, hc2
def gen_waveform(numrel_data, iota, phi): ## FIXME(Gonghan): It seems that wavelabel is never used. # global wavelabel # wavelabel=os.PATH.join(savepath, waveformName.split('/')[-1].replace(".h5","")) f = h5py.File(numrel_data, 'r') # Getting the 2-2 mode polarizations first. hp, hc = get_td_waveform(approximant='NR_hdf5', numrel_data=numrel_data, mass1=f.attrs['mass1'] * mass, mass2=f.attrs['mass2'] * mass, spin1z=f.attrs['spin1z'], spin2z=f.attrs['spin2z'], delta_t=1.0 / sample_frequency, f_lower=30., inclination=iota, coa_phase=phi, distance=1000, mode_array=[[2, 2], [2, -2]]) # Taper waveform for smooth FFTs hp = taper_timeseries(hp, tapermethod="TAPER_START") hc = taper_timeseries(hc, tapermethod="TAPER_START") amp = wfutils.amplitude_from_polarizations(hp, hc) peakAmpTime = amp.sample_times[np.argmax(amp)] '''mode_array=[[2,2], [2,-2]]''' # Getting the full-mode waveform. hp, hc = get_td_waveform(approximant='NR_hdf5', numrel_data=numrel_data, mass1=f.attrs['mass1'] * mass, mass2=f.attrs['mass2'] * mass, spin1z=f.attrs['spin1z'], spin2z=f.attrs['spin2z'], delta_t=1.0 / sample_frequency, f_lower=30., inclination=iota, coa_phase=phi, distance=1000) f.close() # Taper waveform for smooth FFTs hp = taper_timeseries(hp, tapermethod="TAPER_START") hc = taper_timeseries(hc, tapermethod="TAPER_START") amp = wfutils.amplitude_from_polarizations(hp, hc) foft = wfutils.frequency_from_polarizations(hp, hc) # Shift time origin to merger ## FIXME(Gonghan): Not sure how we want to define zero time. sample_times = amp.sample_times - peakAmpTime # sample_times = amp.sample_times # # Trim the timeseries before the CWT # hp_red = hp[:int(sample_frequency)] return { "hp": hp, "hc": hc, "amp": amp, "foft": foft, "sample_times": sample_times }