def test_orbital_symmetry_flags(): # TODO: add 4d2s -- this will give non-trival combinations of this flag """ Check valid combinations of orbital symmetry flags""" EOBNRv2_sur = gws.EvaluateSurrogate(path_to_surrogate) # These three combinations should pass EOBNRv2_sur = gws.EvaluateSurrogate(path_to_surrogate, use_orbital_plane_symmetry=True) modes, t, hp, hc = EOBNRv2_sur(q=1.14,ell=[2],m=[2],mode_sum=False,fake_neg_modes=True) EOBNRv2_sur = gws.EvaluateSurrogate(path_to_surrogate, use_orbital_plane_symmetry=True) modes, t, hp, hc = EOBNRv2_sur(q=1.14,ell=[2],m=[2],mode_sum=False,fake_neg_modes=False) EOBNRv2_sur = gws.EvaluateSurrogate(path_to_surrogate, use_orbital_plane_symmetry=False) modes, t, hp, hc = EOBNRv2_sur(q=1.14,ell=[2],m=[2],mode_sum=False,fake_neg_modes=False) # This should fail with a ValueError. So seeing this error is a passed test try: EOBNRv2_sur = gws.EvaluateSurrogate(path_to_surrogate, use_orbital_plane_symmetry=False) modes, t, hp, hc = EOBNRv2_sur(q=1.14,ell=[2],m=[2],mode_sum=False,fake_neg_modes=True) except ValueError: pass
import gwsurrogate as gws from gwsurrogate import gwtools import numpy as np import matplotlib import matplotlib.pyplot as plt import pandas as pd # ell_m specific modes to pull from data: we are pulling (2,2) modes spec = gws.EvaluateSurrogate('SpEC_q1_10_NoSpin_nu5thDegPoly_exclude_2_0.h5', ell_m=[(2, 2)]) timeLength = 28501 massRatioFirstTerm = [1, 2, 3, 4, 5, 6, 7] massRatioSecondTerm = [.2, .4, .6, .8] combined_mass_ratios = [] # generate mass ratios (1.2 - 9.8) for i in range(len(massRatioFirstTerm)): for j in range(len(massRatioSecondTerm)): massRatio = massRatioFirstTerm[i] + massRatioSecondTerm[j] combined_mass_ratios.append(massRatio) # parse time, cross/plus polarization data, saves to text file in same directory for i in range(len(combined_mass_ratios)): formatted_data = [] modes, times, hp, hc = spec(q=combined_mass_ratios[i], ell=[2], m=[2], mode_sum=False, fake_neg_modes=False)
sur = gwsnew.FastTensorSplineSurrogate() sur.load(ts_filename) # These are useful to have in gws surrogates. Not sure if mandatory. v = [np.load('vandermond/mode%s.npy'%(i)) for i in range(12)] lm_modes = [] for ell in range(2, 4): for m in range(-ell, ell+1): lm_modes.append((ell, m)) print 'Saving gws surrogate...' save_gws_surrogate(out_filename, lm_modes, sur.ei, v, sur.cre, sur.cim) print 'Loading gws surrogate...' sur_new = gws.EvaluateSurrogate(out_filename, use_orbital_plane_symmetry=False) print 'Testing...' x = np.array([1.2, 0.3, 0.4, 0.5, -0.2]) h_ts = sur(x) lm_modes, t, hre, him = sur_new(x, mode_sum=False, fake_neg_modes=False) h_gws = (hre + 1.j*him).T print 'Evaluation was successfull! Checking errors...' max_err = 0. for mode_gws, (ell, m) in zip(h_gws, lm_modes): mode_ts = h_ts[ell, m] err = np.max(abs(mode_ts - mode_gws)) max_err = max(err, max_err)
phi = polarisation angle (often called \psi) -- two waveforms are output, one with phi, one with phi = phi + pi/2 z_rot = a proxy for the phase -- therefore leave fixed ''' q = 1 M = 60. dist = 410. theta = 140. # theta = iota (i.e., inclination angle) phi = 0. # polarisation angle z_rot = 0. # hardcode the phase, Phi = 0. path_to_surrogate = '/home/ethan/LIGO/' surrogate_file = path_to_surrogate + 'SpEC_q1_10_NoSpin_nu5thDegPoly_exclude_2_0.h5' spec = gws.EvaluateSurrogate(surrogate_file, ell_m=[(2, 2)]) ## Calculate the plus and cross components for the phi = 0 case time = np.linspace(-0.4, 0.03, 10**5) _, hp_zero, hc_zero = spec(q=q, M=M, dist=dist, theta=theta, phi=phi, z_rot=z_rot, mode_sum=True, fake_neg_modes=True, samples=time, samples_units='mks')
def test_model_regression(generate_regression_data=False): """ If generate_regression_data = True, this script will generate an hdf5 file to diff against. No regression will be done. If generate_regression_data = False, this script will compare model evaluations to the hdf5 file produced when True. In a typical use case, this regression file will be downloaded. """ if generate_regression_data: h5_file = "model_regression_data.h5" print( "Generating regression data file... Make sure this step is done BEFORE making any code changes!\n" ) print(os.path.exists(h5_file)) if os.path.exists(h5_file): raise RuntimeError("Refusing to overwrite a regression file!") else: h5_file = "test/comparison_data.h5" # assumes pytest runs from project-level folder try: # try importing data. If it doesn't exist, download it fp_regression = h5py.File("test/model_regression_data.h5", 'r') except IOError: print("Downloading regression data...") os.system( 'wget --directory-prefix=test https://www.dropbox.com/s/vxqsr7fjoffxm5w/model_regression_data.h5' ) fp_regression = h5py.File("test/model_regression_data.h5", 'r') # remove models if you don't have them dont_test = [ "EMRISur1dq1e4", # model data not currently available in public "NRSur4d2s_TDROM_grid12", # 10 GB file "NRSur4d2s_FDROM_grid12", # 10 GB file #"SpEC_q1_10_NoSpin_linear_alt", #"SpEC_q1_10_NoSpin_linear", "EOBNRv2", #TODO: this is two surrogates in one. Break up? #"SpEC_q1_10_NoSpin", #"EOBNRv2_tutorial", #"NRHybSur3dq8", #"NRHybSur3dq8Tidal", #"NRSur7dq4" ] # Common directory where all surrogates are assumed to be located surrogate_path = gws.catalog.download_path() # repeatability can be useful for regression tests np.random.seed(0) # for each model, associate its surrogate data file models = [model for model in gws.catalog._surrogate_world] print(models) models_to_test = {} for model in models: surrogate_data = surrogate_path + os.path.basename( gws.catalog._surrogate_world[model][0]) if os.path.isfile(surrogate_data): # surrogate data file exists models_to_test[model] = surrogate_data else: # file missing msg = "WARNING: Surrogate missing!!!\n" msg += "Surrogate data assumed to be in the path %s.\n" % surrogate_data msg += "If the data is somewhere else, change the path or move the file.\n\n" msg += "To download this surrogate, from ipython do\n\n >>> gws.catalog.pull(%s)\n" % model print(msg) time.sleep(1) # also test the tutorial surrogate models_to_test["EOBNRv2_tutorial"] = gws.__path__[ 0] + "/../tutorial/TutorialSurrogate/EOB_q1_2_NoSpin_Mode22/" # remove models from testing... for i in dont_test: try: models_to_test.pop(i) print("model %s removed from testing" % i) except KeyError: print("model %s cannot be removed" % i) fp = h5py.File(h5_file, "w") # for each model, select three random points to evaluate at param_samples_tested = [] for model, datafile in models_to_test.items(): print("Generating regression data for model = %s" % model) print(datafile) if model in surrogate_old_interface: sur = gws.EvaluateSurrogate(datafile) p_mins = sur.param_space.min_vals() p_maxs = sur.param_space.max_vals() elif model in surrogate_loader_interface: # sur = gws.LoadSurrogate(datafile) # tidal and aligned models use the same h5 file (so wrong one loaded) sur = gws.LoadSurrogate(model) try: p_mins = sur._sur_dimless.param_space.min_vals() p_maxs = sur._sur_dimless.param_space.max_vals() except AttributeError: # NRSur7dq4 does not have object sur._sur_dimless.param_space p_mins = None p_maxs = None else: sur = surrogate.FastTensorSplineSurrogate() sur.load(datafile) p_mins = sur.param_space.min_vals() p_maxs = sur.param_space.max_vals() print("parameter minimum values", p_mins) print("parameter maximum values", p_maxs) param_samples = [] if generate_regression_data: # pick new points to compute regression data at for i in range(3): # sample parameter space 3 times if model in list(model_sampler.keys()): custom_sampler = model_sampler[model] x, tidOpts, pecOpts = custom_sampler( i) # [q, chiA, chiB], tidOpts else: # default sampler for spin-aligned BBH models x = [] # [q, chiAz, chiBz] for j in range(len(p_mins)): xj_min = p_mins[j] xj_max = p_maxs[j] tmp = float(np.random.uniform(xj_min, xj_max, size=1)) x.append(tmp) tidOpts = None pecOpts = None param_samples.append([x, tidOpts, pecOpts]) else: # get point at which to compute comparison waveform data for i in range(3): if model in list( model_sampler.keys()): # use sample points if provided custom_sampler = model_sampler[model] x, tidOpts, pecOpts = custom_sampler( i) # [q, chiA, chiB], tidOpts else: # pull regression points from regression data file; none-tidal models only print(model + "/parameter%i/parameter" % i) x = [] x.append( list(fp_regression[model + "/parameter%i/parameter" % i][:])) # [q, chiAz, chiBz] x = list(fp_regression[model + "/parameter%i/parameter" % i][:]) # [q, chiAz, chiBz] tidOpts = None pecOpts = None param_samples.append([x, tidOpts, pecOpts]) param_samples_tested.append(param_samples) model_grp = fp.create_group(model) for i, ps in enumerate(param_samples): x = ps[0] tidOpts = ps[1] pecOpts = ps[2] if model in surrogate_old_interface: ps_float = x[0] # TODO: generalize interface modes, t, hp, hc = sur(q=ps_float, mode_sum=False, fake_neg_modes=True) else: if model in surrogate_loader_interface: q = x[0] if type(x[1]) is np.float64 or type(x[1]) is float: # chiz chiA = np.array([0, 0, x[1]]) chiB = np.array([0, 0, x[2]]) elif len(x[1]) == 3: # spin vector chiA = np.array(x[1]) chiB = np.array(x[2]) else: raise ValueError try: # Regression samples outside of the training interval. # Warnings are raised (as they should) but could # appear bad to a new user if model in ["NRSur7dq4"]: with warnings.catch_warnings(): warnings.simplefilter("ignore") t, h, dyanmics = sur(q, chiA, chiB, f_low=0.0, tidal_opts=tidOpts, precessing_opts=pecOpts) else: t, h, dyanmics = sur(q, chiA, chiB, f_low=0.0, tidal_opts=tidOpts, precessing_opts=pecOpts) except ValueError: # some models do not allow for f_low=0.0 and require a time step # step size, Units of M # initial frequency, Units of cycles/M t, h, dyanmics = sur(q, chiA, chiB, dt=0.25, f_low=3.e-3, tidal_opts=tidOpts, precessing_opts=pecOpts) else: h = sur(x) try: h_np = [h[mode] for mode in sur.mode_list] except AttributeError: # for new interface h_np = [h[mode] for mode in sur._sur_dimless.mode_list] h_np = np.vstack(h_np) hp = np.real(h_np) hc = np.imag(h_np) samplei = model_grp.create_group("parameter" + str(i)) if model in list(model_sampler.keys()): # model samplers return a list of lists, which we flatten into # a list of numbers for storing in an h5 dataset x = flatten_params(x) samplei.create_dataset("parameter", data=x) samplei.create_dataset("hp", data=hp, dtype='float32') samplei.create_dataset("hc", data=hc, dtype='float32') fp.close() if not generate_regression_data: fp = h5py.File(h5_file, "r") # reopen comparison data for model in models_to_test.keys(): print("testing model %s ..." % model) for i in range(3): # 3 parameter samples hp_regression = fp_regression[model + "/parameter%i/hp" % i][:] hc_regression = fp_regression[model + "/parameter%i/hp" % i][:] hp_comparison = fp[model + "/parameter%i/hp" % i][:] hc_comparison = fp[model + "/parameter%i/hp" % i][:] if model == "NRHybSur3dq8": local_rtol = rtol_gsl else: local_rtol = rtol_gsl np.testing.assert_allclose(hp_regression, hp_comparison, rtol=local_rtol, atol=atol) np.testing.assert_allclose(hc_regression, hc_comparison, rtol=local_rtol, atol=atol) # fails due to round-off error differences of different machines #fp_regression.close() #process = subprocess.Popen(["h5diff", "test/model_regression_data.h5",h5_file], # stdin=subprocess.PIPE, # stdout=subprocess.PIPE, # stderr=subprocess.PIPE) #returncode = process.wait() #stdout, stderr = process.communicate() #if returncode == 0: # assert(True) #else: # print(stdout) # print(stderr) # assert(False) print("models tested... ")