<jupyter_start><jupyter_text>Lesson 1: Evaluate and plot surrogates<jupyter_code>### setup system path ###
# NOTE: This step is NOT needed if gwsurrogate was installed from pip, with "python setup.py install" 
# or if PYTHONPATH has been set (see README)
import sys, os
path_to_gws = '/home/balzani57/Repo/GitRepos/Codes/gwsurrogate/'
sys.path.append(path_to_gws)
### import the gwsurrogate and gwtools modules and load an existing surrogate ###
import gwsurrogate as gws
import gwtools

# assumes notebook launched from "notebooks" directory
path_to_surrogate = path_to_gws+'tutorial/TutorialSurrogate/EOB_q1_2_NoSpin_Mode22/l2_m2_len12239M_SurID19poly/'
EOBNRv2_sur       = gws.EvaluateSingleModeSurrogate(path_to_surrogate) # multi-mode evaluation covered in other notebooks

### import other useful packages ###
#%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
### evaluate and plot an EOB surrogate waveform (physical) ###
t, hp, hc  = EOBNRv2_sur(q=1.7, M=80.0, dist=1.0, phi_ref = 0.0, f_low = 10.0)
amp, phase = EOBNRv2_sur.amp_phase(hp + 1j*hc)

gwtools.plot_pretty(t, [hp, hc])
plt.plot(t,amp,'r')
plt.xlabel('t (seconds)')
plt.show()
### Variety of helper functions, for example, compute the mode's phase at merger...
phi_m = EOBNRv2_sur.phi_merger(hp + 1j*hc)
print('current phase is '+str( np.mod(EOBNRv2_sur.phi_merger(hp + 1j*hc),2.0*np.pi) ) )

### ...modify h, without generating a new waveform, such that the phase is now 2.0
h_adj = EOBNRv2_sur.adjust_merger_phase(hp + 1j*hc,2.0)
print('new phase is '+str( np.mod(EOBNRv2_sur.phi_merger(h_adj),2.0 * np.pi) ) )
### direct plotting is also supported (dimensionless) ###
EOBNRv2_sur.plot_sur(1.7);
### if you try to evaluate the surrogate outside of its training range, an error is thrown ###
t1, hp1, hc1 = EOBNRv2_sur(q=2.7, M=80.0, dist=1.0)<jupyter_output><empty_output><jupyter_text>Lesson 2: Sampling the surrogate at different times<jupyter_code># Surrogate at q=1.2 with original time sampling (i.e. the one for which it was built)
t, hp, hc = EOBNRv2_sur(q=1.2)
# Surrogate at q=1.2 with 3000 samples in an enlarged interval of time
# Sampling outside of the training time interval returns zeros
t_resamp, hp_resamp, hc_resamp = EOBNRv2_sur(1.2,times=np.linspace(EOBNRv2_sur.tmin-1000,EOBNRv2_sur.tmax+1000,num=3000))
gwtools.plot_pretty(t, [hp, hc],1)
gwtools.plot_pretty(t_resamp, [hp_resamp, hc_resamp],2)
plt.show()<jupyter_output><empty_output><jupyter_text>Lesson 3: Surrogate properties<jupyter_code>### Greedy points and eim indicies ###
t, hp, hc = EOBNRv2_sur(1.7,80.0,1.0)

eim_pts    = EOBNRv2_sur.eim_indices
T_eim      = t[eim_pts]
greedy_pts = EOBNRv2_sur.greedy_points

gwtools.plot_pretty(t, [hp, hc])
plt.plot(T_eim,np.zeros(eim_pts.shape),'r*',markersize=15)
plt.show()

print('Mass ratios defining the basis: ', greedy_pts)
### Temporal information is stored with dimensionless 't/M' units ###
print('temporal units is '+EOBNRv2_sur.t_units)
print('temporal sampling is '+str(EOBNRv2_sur.dt))
print('sampling rate is '+str(1.0/EOBNRv2_sur.dt))
print( 'initial time is '+str(EOBNRv2_sur.tmin))
print( 'final time is '+str(EOBNRv2_sur.tmax))<jupyter_output><empty_output><jupyter_text>Lesson 4: Surrogate basis functionsWe now show two ways of recovering the i^th physical RB waveform. The first way evalutes the surrogate at the 5th greedy point q_5. The second way uses the Vandermonde matrix V and the GS matrix R (defined as A = QR) to exactly recover the 5th physical RB waveform. Having two (kinda) independent ways to compute h_5 provides a check of R,V, and the surrogate model error at this value of q.<jupyter_code>### plot the ith cardinal (B) basis which appears as h_surrogate = Sum_i B_i(t) h(T_i)  ###
i = 2
times = EOBNRv2_sur.time()
b_i   = EOBNRv2_sur.basis(i-1,'cardinal')

gwtools.plot_pretty(times,[b_i.real,b_i.imag],1)
plt.title('Cardinal basis')

### use the matrix V, as E = B V, to exactly recover the ith orthonormal basis E ###
e_i = EOBNRv2_sur.basis(i-1,'orthogonal')

gwtools.plot_pretty(times,[e_i.real,e_i.imag],2)
plt.title('Orthogonal basis')

### use the matrix R, as H = E R, to recover the ith physical basis H ###
h_i = EOBNRv2_sur.basis(i-1,'waveform')

gwtools.plot_pretty(times,[h_i.real,h_i.imag],3)
plt.title('Waveform basis')

### use the surrogate model to evaluate for the ith physical basis ###
junk, hp_i_surr, hc_i_surr = EOBNRv2_sur(EOBNRv2_sur.greedy_points[i-1])
nrm_i = EOBNRv2_sur.norm_eval(EOBNRv2_sur.greedy_points[i-1]) # normalization constant for comparison with normalized basis
hp_i_surr = hp_i_surr / nrm_i 
hc_i_surr = hc_i_surr / nrm_i
h_i_surr = hp_i_surr + 1j*hc_i_surr

gwtools.plot_pretty(times,[hp_i_surr,hc_i_surr],4)
plt.title('Waveform basis via surrogate model')

### plot the difference between the ith physical basis and its surrogate -- consistency and error check ###
gwtools.plot_pretty(times,[h_i.real - hp_i_surr,h_i.imag - hc_i_surr],5,'semilogy')
plt.title('Difference between physical waveform basis and its surrogate prediction')

plt.show()
### check basis orthonormality (using Euclidean inner product) ###
### NOTE: Basis orthogonal on physical grid (in seconds). See surrogate's info.data file
dt  = 1.0/2048.0
e_5 = EOBNRv2_sur.basis(5,'orthogonal')
e_6 = EOBNRv2_sur.basis(6,'orthogonal')
print( '<e_5,e_6> = ', np.sum(e_5*np.conj(e_6)) * dt)
print( '<e_5,e_5> = ', np.sum(e_5*np.conj(e_5)) * dt)
### plotting the waveform basis using the surrogate is also a built-in function ###
EOBNRv2_sur.plot_rb(4)<jupyter_output><empty_output><jupyter_text>Lesson 5: General (multi-mode) surrogates & training regionsLessons 1-4 used the single-mode EvaluateSingleModeSurrogate class, which is useful when you need access to low-level data (like the basis). For simply using a surrogate mode, EvaluateSurrogate should be used. The behavior is very similar<jupyter_code># notice this way of loading the surrogate also displays useful information
path_to_surrogate = path_to_gws+'tutorial/TutorialSurrogate/EOB_q1_2_NoSpin_Mode22/'
EOBNRv2_sur = gws.EvaluateSurrogate(path_to_surrogate)
# we can directly access information about the surrogate's training region
print EOBNRv2_sur.param_space.min_vals()
print EOBNRv2_sur.param_space.max_vals()<jupyter_output><empty_output><jupyter_text>Lesson 6: Download surrogates from a serverSurrogate may be located on a server. gwsurrogate provides a list of the locations as well as download tools<jupyter_code>### view all available surrogates ###
gws.catalog.list()
### display the default location for all surrogate downloads ###
gws.catalog.download_path()
# NOTE: if the surrogate does not download, proceed to 
# https://www.black-holes.org/data/surrogates/data/files

### download a surrogate (this will take a moment, check the terminal for progress) ##
#surr_path = gws.catalog.pull('SpEC_q1_10_NoSpin_linear_alt')

# ...or specify a custom download location as 
#surr_path = gws.catalog.pull('SpEC_q1_10_NoSpin','MY_PATH')
# load the multimode numerical relativity surrogate you've just downloaded #

# path to surrogate can be a custom location
# if the previous cell was executed, let surr_path be the default one
#surr_path = "/home/balzani57/Repo/GitRepos/Codes/gwsurrogate/surrogate_downloads/SpEC_q1_10_NoSpin_nu5thDegPoly_exclude_2_0.h5"

spec = gws.EvaluateSurrogate(surr_path)
# evaluate and plot a surrogate #
t, hp, hc = spec(q=3.14,ell=[2],m=[2],fake_neg_modes=False)

gwtools.plot_pretty(t,[hp,hc],showQ=False)
plt.plot(t,np.abs(hp+1.0j*hc),'blue')
plt.xlabel('$t/M$')
plt.title('(2,2) mode for q = 3.14')
plt.show()<jupyter_output><empty_output><jupyter_text>Generating negative m modes using symmetryThe symmetry of non-precessing binary systems (reflections about the orbital plane) allow negative m modes to be computed from positive m modes (see See Eq. 78 of Kidder, Physical Review D 77, 044016 (2008)). Typically, non-precessing waveform surrogate models of binary systems only provide models for the m>=0 modes. The negative m modes are then found from known formulas.<jupyter_code># Evaluate and plot a negative m mode using fake_neg_modes
# Note that mode_sum must be set to false -- this returns a list of modes
modes, t, hp, hc = spec(q=3.14,ell=[2],m=[2],mode_sum=False,fake_neg_modes=True)

print(modes)

gwtools.plot_pretty(t,[hp[:,0],hc[:,0]],fignum=1,showQ=False)
plt.plot(t,np.abs(hp+1.0j*hc),'blue')
plt.xlabel('$t/M$')
plt.title('(2,-2) mode for q = 3.14')

gwtools.plot_pretty(t,[hp[:,1],hc[:,1]],fignum=2,showQ=False)
plt.plot(t,np.abs(hp+1.0j*hc),'blue')
plt.xlabel('$t/M$')
plt.title('(2,2) mode for q = 3.14')

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12110686580988769, 'fraction_numerical': 0.02755586430473544, 'mean_word_length': 5.949316170555108, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 32, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '358941', 'license': 'MIT', 'n_tokens_mistral': 3503, 'n_tokens_neox': 3232, 'n_words': 857, 'path': 'tutorial/notebooks/basics.ipynb', 'repo_name': 'tousifislam/gwsurrogate', 'size': '8637'}