diff --git a/docs/conf.py b/docs/conf.py index f504361..3f2a592 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,6 +9,7 @@ project = 'pycbc_wferrors_plugin' import datetime + year = datetime.datetime.now().year copyright = f'{year}, The PyCBC Team' # copyright = '2025, Sumit Kumar and Max Melching and Frank Ohme' @@ -29,7 +30,7 @@ 'm2r2', # including markdown files # 'sphinx_mdinclude', # including markdown files -> then comment m2r2 -> seems to work much better -> but not compatible with nbsphinx... 'nbsphinx', - 'nbsphinx_link' + 'nbsphinx_link', ] @@ -37,7 +38,6 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output @@ -51,6 +51,5 @@ 'collapse_navigation': False, # Makes navigation expandable 'sticky_navigation': True, 'navigation_depth': 4, - 'titles_only': False + 'titles_only': False, } - diff --git a/examples/notebooks/example_usage.ipynb b/examples/notebooks/example_usage.ipynb index 90aa932..4dbdeb7 100644 --- a/examples/notebooks/example_usage.ipynb +++ b/examples/notebooks/example_usage.ipynb @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -66,8 +66,8 @@ " 'mass2': 20,\n", " 'f_lower': 20,\n", " 'f_final': 1024,\n", - " 'delta_f': 1/64,\n", - " 'delta_t': 1/2048,\n", + " 'delta_f': 1.0 / 64.0,\n", + " 'delta_t': 1.0 / 2048.0,\n", " 'spin1z': 0,\n", " 'spin2z': 0,\n", " 'distance': 100,\n", @@ -117,8 +117,8 @@ "wf_no_mod_params = {\n", " 'modification_type': 'constant_shift',\n", " 'error_in_phase': 'relative',\n", - " 'delta_amplitude': 0.,\n", - " 'delta_phase': 0.,\n", + " 'delta_amplitude': 0.0,\n", + " 'delta_phase': 0.0,\n", "}\n", "\n", "hpf_no_mod, hcf_no_mod = get_fd_waveform(\n", @@ -199,7 +199,7 @@ " 'modification_type': 'constant_shift',\n", " 'error_in_phase': 'relative',\n", " 'delta_amplitude': 0.1,\n", - " 'delta_phase': 0.,\n", + " 'delta_phase': 0.0,\n", "}\n", "\n", "hpf_amp_mod, hcf_amp_mod = get_fd_waveform(\n", @@ -246,7 +246,7 @@ "wf_phase_mod_params = {\n", " 'modification_type': 'constant_shift',\n", " 'error_in_phase': 'relative',\n", - " 'delta_amplitude': 0.,\n", + " 'delta_amplitude': 0.0,\n", " 'delta_phase': 0.1,\n", "}\n", "\n", @@ -350,7 +350,9 @@ "f_high_calibration = wf_params['f_final']\n", "\n", "n_wf_nodal_points = 10\n", - "wf_nodal_points = np.logspace(np.log10(f_low_calibration), np.log10(f_high_calibration), n_wf_nodal_points)\n", + "wf_nodal_points = np.logspace(\n", + " np.log10(f_low_calibration), np.log10(f_high_calibration), n_wf_nodal_points\n", + ")\n", "\n", "\n", "ampl_mean_err = 0.1\n", @@ -360,8 +362,12 @@ "phase_stddev_err = 0.05\n", "\n", "np.random.seed(42)\n", - "delta_amplitude_arr = np.random.standard_normal(n_wf_nodal_points)*ampl_stddev_err + ampl_mean_err\n", - "delta_phase_arr = np.random.standard_normal(n_wf_nodal_points)*phase_stddev_err + phase_mean_err\n", + "delta_amplitude_arr = (\n", + " np.random.standard_normal(n_wf_nodal_points) * ampl_stddev_err + ampl_mean_err\n", + ")\n", + "delta_phase_arr = (\n", + " np.random.standard_normal(n_wf_nodal_points) * phase_stddev_err + phase_mean_err\n", + ")\n", "\n", "\n", "wf_mod_spline_params = {\n", @@ -519,8 +525,8 @@ " # t_gps=float(t_ref),\n", ")\n", "\n", - "hf_ref = fp*hpf_ref + fc*hcf_ref\n", - "hf_mod_spline = fp*hpf_mod_spline + fc*hcf_mod_spline\n", + "hf_ref = fp * hpf_ref + fc * hcf_ref\n", + "hf_mod_spline = fp * hpf_mod_spline + fc * hcf_mod_spline\n", "\n", "\n", "# from pycbc.waveform import apply_fseries_time_shift\n", diff --git a/setup.py b/setup.py index 4731413..d722173 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ - """ setup.py file for waveform-errors from pycbc waveform plugin package """ @@ -10,29 +9,33 @@ 'version_file': '_pycbc_wferrors_version.py', 'version_scheme': 'no-guess-dev', 'local_scheme': 'dirty-tag', - 'fallback_version': '0.1.0' + 'fallback_version': '0.1.0', } setup( - name = 'pycbc-wferrors', - use_scm_version = version_config, - description = 'An waveform plugin for systematic errors for PyCBC', - long_description = open('descr.rst').read(), - author = 'The PyCBC team', - author_email = 'sumit.kumar@aei.mpg.de', - url = 'http://www.pycbc.org/', - keywords = ['pycbc', 'signal processing', 'gravitational waves'], - setup_requires = [ + name='pycbc-wferrors', + use_scm_version=version_config, + description='An waveform plugin for systematic errors for PyCBC', + long_description=open('descr.rst').read(), + author='The PyCBC team', + author_email='sumit.kumar@aei.mpg.de', + url='http://www.pycbc.org/', + keywords=['pycbc', 'signal processing', 'gravitational waves'], + setup_requires=[ 'setuptools>=64', 'setuptools_scm>=8', 'wheel', ], - install_requires = ['pycbc'], - py_modules = ['wferrors'], - entry_points = {"pycbc.waveform.fd":["wferrors = wferrors:amplitude_phase_modification_fd", - "wferrors_2p = wferrors:amplitude_phase_modification_both_polarization_fd"]}, - classifiers = [ + install_requires=['pycbc'], + py_modules=['wferrors'], + entry_points={ + "pycbc.waveform.fd": [ + "wferrors = wferrors:amplitude_phase_modification_fd", + "wferrors_2p = wferrors:amplitude_phase_modification_both_polarization_fd", + ] + }, + classifiers=[ 'Programming Language :: Python', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', @@ -57,6 +60,5 @@ 'nbsphinx-link', 'lxml_html_clean', # Needed by nbsphinx ], - - } + }, ) diff --git a/wferrors.py b/wferrors.py index c4955a4..63eed66 100644 --- a/wferrors.py +++ b/wferrors.py @@ -7,17 +7,17 @@ def amplitude_phase_modification_fd(**kwds): """ This function applies the Amplitude-Phase modification, described in - Kumar, Melching, Ohme (2025), to the base waveform approximant in + Kumar, Melching, Ohme (2025), to the base waveform approximant in frequency domain. Input in kwds: error_in_phase: 'relative' or 'absolute' This argument specify the type of errors to be applied. - baseline_approximant: FD approximant of the reference waveform model to + baseline_approximant: FD approximant of the reference waveform model to modified. modification_type: 'cubic_spline', 'cubic_spline_nodes', or 'constant_shift' - 'cubic_spline': If this option is passed, the dictionary should + 'cubic_spline': If this option is passed, the dictionary should includes array of delta_amplitude, delta_phase, and nodal_points 'cubic_spline_nodes': When we specify this modification_type, the lower and upper limits of the frequency should be given along with number @@ -97,9 +97,9 @@ def amplitude_phase_modification_fd(**kwds): + delta_phase ) elif dict_waveform_modification['modification_type'] == 'cubic_spline_nodes': - f_lower = (dict_waveform_modification.get('f_lower_wferror', - default=dict_waveform_modification['f_lower']) - ) + f_lower = dict_waveform_modification.get( + 'f_lower_wferror', default=dict_waveform_modification['f_lower'] + ) f_high_wferror = dict_waveform_modification['f_high_wferror'] n_nodes_wferror = int(dict_waveform_modification['n_nodes_wferror']) wf_nodal_points = numpy.logspace( @@ -158,6 +158,7 @@ def amplitude_phase_modification_fd(**kwds): return hp, hc + def amplitude_phase_modification_both_polarization_fd(**kwds): """Modify amplitude and phase of waveform polarizations in frequency domain.""" @@ -178,18 +179,14 @@ def amplitude_phase_modification_both_polarization_fd(**kwds): delta_amplitude_plus_interp = CubicSpline( wf_nodal_points, delta_amplitude_plus_arr ) - delta_phase_plus_interp = CubicSpline( - wf_nodal_points, delta_phase_plus_arr - ) + delta_phase_plus_interp = CubicSpline(wf_nodal_points, delta_phase_plus_arr) delta_amplitude_cross_arr = dict_waveform_modification['delta_amplitude_cross'] delta_phase_cross_arr = dict_waveform_modification['delta_phase_cross'] delta_amplitude_cross_interp = CubicSpline( wf_nodal_points, delta_amplitude_cross_arr ) - delta_phase_cross_interp = CubicSpline( - wf_nodal_points, delta_phase_cross_arr - ) + delta_phase_cross_interp = CubicSpline(wf_nodal_points, delta_phase_cross_arr) # Modify amplitude and phase for Plus and Cross polarization Am_plus = waveform.amplitude_from_frequencyseries(hp) * ( @@ -222,8 +219,12 @@ def amplitude_phase_modification_both_polarization_fd(**kwds): delta_phase_cross = dict_waveform_modification['delta_phase_cross'] # Modify amplitude and phase for Plus and Cross polarization - Am_plus = waveform.amplitude_from_frequencyseries(hp) * (1 + delta_amplitude_plus) - Am_cross = waveform.amplitude_from_frequencyseries(hc) * (1 + delta_amplitude_cross) + Am_plus = waveform.amplitude_from_frequencyseries(hp) * ( + 1 + delta_amplitude_plus + ) + Am_cross = waveform.amplitude_from_frequencyseries(hc) * ( + 1 + delta_amplitude_cross + ) if dict_waveform_modification['error_in_phase'] == 'relative': Ph_plus = waveform.phase_from_frequencyseries( @@ -233,17 +234,19 @@ def amplitude_phase_modification_both_polarization_fd(**kwds): hc, remove_start_phase=False ) * (1 + delta_phase_cross) elif dict_waveform_modification['error_in_phase'] == 'absolute': - Ph_plus = waveform.phase_from_frequencyseries( - hp, remove_start_phase=False - ) + delta_phase_plus - Ph_cross = waveform.phase_from_frequencyseries( - hc, remove_start_phase=False - ) + delta_phase_cross + Ph_plus = ( + waveform.phase_from_frequencyseries(hp, remove_start_phase=False) + + delta_phase_plus + ) + Ph_cross = ( + waveform.phase_from_frequencyseries(hc, remove_start_phase=False) + + delta_phase_cross + ) elif modification_type == 'cubic_spline_nodes': - f_lower = (dict_waveform_modification.get('f_lower_wferror', - default=dict_waveform_modification['f_lower']) - ) + f_lower = dict_waveform_modification.get( + 'f_lower_wferror', default=dict_waveform_modification['f_lower'] + ) f_high_wferror = dict_waveform_modification['f_high_wferror'] n_nodes_wferror = int(dict_waveform_modification['n_nodes_wferror']) @@ -251,22 +254,30 @@ def amplitude_phase_modification_both_polarization_fd(**kwds): numpy.log10(f_lower), numpy.log10(f_high_wferror), n_nodes_wferror ) - delta_amplitude_plus_arr = numpy.hstack([ - dict_waveform_modification[f'wferror_amplitude_plus_{i}'] - for i in range(len(wf_nodal_points)) - ]) - delta_phase_plus_arr = numpy.hstack([ - dict_waveform_modification[f'wferror_phase_plus_{i}'] - for i in range(len(wf_nodal_points)) - ]) - delta_amplitude_cross_arr = numpy.hstack([ - dict_waveform_modification[f'wferror_amplitude_cross_{i}'] - for i in range(len(wf_nodal_points)) - ]) - delta_phase_cross_arr = numpy.hstack([ - dict_waveform_modification[f'wferror_phase_cross_{i}'] - for i in range(len(wf_nodal_points)) - ]) + delta_amplitude_plus_arr = numpy.hstack( + [ + dict_waveform_modification[f'wferror_amplitude_plus_{i}'] + for i in range(len(wf_nodal_points)) + ] + ) + delta_phase_plus_arr = numpy.hstack( + [ + dict_waveform_modification[f'wferror_phase_plus_{i}'] + for i in range(len(wf_nodal_points)) + ] + ) + delta_amplitude_cross_arr = numpy.hstack( + [ + dict_waveform_modification[f'wferror_amplitude_cross_{i}'] + for i in range(len(wf_nodal_points)) + ] + ) + delta_phase_cross_arr = numpy.hstack( + [ + dict_waveform_modification[f'wferror_phase_cross_{i}'] + for i in range(len(wf_nodal_points)) + ] + ) delta_amplitude_plus_interp = CubicSpline( wf_nodal_points, delta_amplitude_plus_arr @@ -275,9 +286,7 @@ def amplitude_phase_modification_both_polarization_fd(**kwds): delta_amplitude_cross_interp = CubicSpline( wf_nodal_points, delta_amplitude_cross_arr ) - delta_phase_cross_interp = CubicSpline( - wf_nodal_points, delta_phase_cross_arr - ) + delta_phase_cross_interp = CubicSpline(wf_nodal_points, delta_phase_cross_arr) # Modify amplitude and phase for Plus and Cross polarization Am_plus = waveform.amplitude_from_frequencyseries(hp) * ( @@ -306,10 +315,11 @@ def amplitude_phase_modification_both_polarization_fd(**kwds): raise TypeError("Currently, no other modification are supported") # Apply the correction to the base model - hp.data = numpy.vectorize(complex)(Am_plus * numpy.cos(Ph_plus), - Am_plus * numpy.sin(Ph_plus)) - hc.data = numpy.vectorize(complex)(Am_cross * numpy.cos(Ph_cross), - Am_cross * numpy.sin(Ph_cross)) + hp.data = numpy.vectorize(complex)( + Am_plus * numpy.cos(Ph_plus), Am_plus * numpy.sin(Ph_plus) + ) + hc.data = numpy.vectorize(complex)( + Am_cross * numpy.cos(Ph_cross), Am_cross * numpy.sin(Ph_cross) + ) return hp, hc -