Quickstart¶
This section illustrates lensingGW
’s core functionalities through
worked-out examples. They demonstrate the solver usage and the simulation of
the lensed and unlensed gravitational signals.
The lens model is specified through a list of lens profile names and a list of related parameters. It is handled through a forked version of Lenstronomy (original version here): any lens profile implemented therein can be used.
Ready-to-use python
scripts implementing the following examples are provided along with each subsection and at the end of the section.
Solve the lens model¶
Radians¶
We first define the lens configuration: we use radians, which is lensingGW
’s default.
As an illustration, we consider two point lenses with Einstein radii \(\theta_{E_1}\) and \(\theta_{E_2}\), whose parameters we have defined in kwargs_lens_list
# lens model
lens_model_list = ['POINT_MASS', 'POINT_MASS']
kwargs_lens_list = [{'center_x': 6.9e-11,'center_y': 0.0, 'theta_E': thetaE1} , {'center_x': -6.9e-11,'center_y': 0.0, 'theta_E': thetaE2}]
We then specify the solver settings
# solver setup
solver_settings = {'SearchWindowMacro': 4*thetaE1,
'SearchWindow' : 4*thetaE2}
from lensinggw.solver.images import microimages
# solve for the image positions with the two-step procedure
Img_ra, Img_dec, MacroImg_ra, MacroImg_dec, pixel_width = microimages(source_pos_x = 1.39e-11,
source_pos_y = 1.20e-10,
lens_model_list = lens_model_list,
kwargs_lens = kwargs_lens_list,
**solver_settings)
solver_settings.update({'Verbose' : True})
The verbosity is a useful diagnostic in non-converging cases, as it allows to identify the problematic part of the iteration.
Image properties
Magnifications, time delays and Morse indices can be accessed through the related modules
from lensinggw.utils.utils import TimeDelay, magnifications, getMinMaxSaddle
# time delays, magnifications, Morse indices
tds = TimeDelay(Img_ra, Img_dec,
source_pos_x = 1.39e-11, source_pos_y = 1.20e-10,
zL = 0.5 , zS = 2.0,
lens_model_list, kwargs_lens_list)
mus = magnifications(Img_ra, Img_dec, lens_model_list, kwargs_lens_list)
ns = getMinMaxSaddle(Img_ra, Img_dec, lens_model_list, kwargs_lens_list)
By default, the solver considers the first profile in lens_model_list as macromodel and applies the two-step procedure to all the macroimages. It sets the same precision requirement on both types of images, as well as the same number of pixels and the same grid sizes for the iterations. These items can be customized through the solver settings. A detailed description of the available options can be found in the solver technical notes.
Arbitrary units¶
lensingGW
supports arbitrary coordinate units, defined as \(x_{\mathrm{a.u.}} = x_{\mathrm{radians}}/ \alpha\), where \(\alpha\) is a constant.
To use arbitrary units, all input must be given in the scaled coordinate system and the scaled flag must be enabled in the
routines involving coordinates or conversions to physical units.# solver setup
solver_settings = {'Scaled' : True, # indicate that the input is in scaled units
'ScaleFactor' : thetaE, # and the scale factor
'SearchWindowMacro': 4*thetaE1/thetaE, # scaled input
'SearchWindow' : 4*thetaE2/thetaE} # scaled input
# time delays, magnifications, Morse indices
tds = TimeDelay(Img_ra, Img_dec, # already in scaled units
source_pos_x = 1.39e-11/thetaE, source_pos_y = 1.20e-10/thetaE, # scaled input
zL = 0.5 , zS = 2.0,
lens_model_list, kwargs_lens_list,
scaled = solver_settings['Scaled'], # indicate that the input is in scaled units
scale_factor = solver_settings['ScaleFactor']) # and the scale factor
The magnification and Morse indices computation doesn’t need modifications, provided that all radians input has been scaled. This includes the lens parameters and the source position.
Multi-component macromodel¶
lensingGW
considers the first profile in lens_model_list as macromodel. However, users can
indicate the profiles that form the macromodel by specifying the matching indices in the lens list.
This allows to indicate a different profile or multi-component macromodels.solver_settings.update({'MacroIndex' : [0,1]})
If the number of specified indices corresponds to the number of lens profiles, all the deflectors are considered as part of the macromodel and only the macroimages are investigated.
Only macromodel¶
If the lens model is composed of a macromodel and a micromodel (such as multiple microlenses), users can require the study of the macromodel only by enabling an appropriate flag in the solver settings
solver_settings.update({'OnlyMacro': True})
enable OnlyMacro and change the lens profile/profile group indicated as macromodel - assesses the impact of the macromodel components on the images of the macromodel
disable OnlyMacro and change the lens profile/profile group indicated as macromodel - assesses the impact of the macromodel components on the images of the complete model
Simulate gravitational waves¶
Configuration files
If gravitational-wave (GW) signals are requested, a configuration file specifying the binary parameters and the waveform settings
has to be provided to lensingGW
. A template configuration file
with explanations of each entry and a ready-to-use configuration file
are provided in examples/ini_files on GitLab.
Note on angles
lensingGW
. This only affects the angles specified in the waveform configuration file:
although any routine of lensingGW
supports the definition of arbitrary units for the source coordinates,
the source right ascension and declination in the configuration file must by expressed in radians.Interferometers’ noise curves
Power spectral densities (PSDs) have to be provided for each interferometer in which the waveform is requested. Advanced LIGO and Advanced Virgo design PSDs released by the LIGO/Virgo Collaborations are provided in examples/psds on GitLab.
Get the unlensed gravitational waves¶
To generate unlensed waveforms, lensingGW
’s signal model has to be initialized through the configuration file
from lensinggw.waveform.waveform import gw_signal
# read the waveform parameters
config_file = 'ini_files/waveform_config.ini'
# instantiate the waveform model
waveform_model = gw_signal(config_file)
Polarizations, strains and their frequencies can be accessed through lensingGW
’s unlensed routines
# compute the unlensed waveform polarizations, strains in the requested detectors and their frequencies
freqs, hp_tilde, hc_tilde, strain_dict = waveform_model.unlensed_gw()
# and their signal-to-noise-ratios
SNR_dict = waveform_model.unlensed_snr()
The strain and SNR dictionaries allow to access information of each detector individually
# access an unlensed strain
sH1 = strain_dict['H1']
Get the lensed gravitational waves¶
# compute the lensed waveform polarizations, strains in the requested detectors and their frequencies
waveform_model.lensed_gw(Img_ra, Img_dec,
source_pos_x = 1.39e-11, source_pos_y = 1.20e-10,
zL = 0.5 , zS = 2.0,
lens_model_list,
kwargs_lens_list)
# and their signal-to-noise-ratios
waveform_model.lensed_snr(Img_ra, Img_dec,
source_pos_x = 1.39e-11, source_pos_y = 1.20e-10,
zL = 0.5 , zS = 2.0,
lens_model_list,
kwargs_lens_list)
Arbitrary units
If the input is in arbitrary units, the scaling has to be notified to the lensed waveform routines by enabling the scaled flag and indicating the scale factor. The previous lines can be modified to use \(\alpha = \theta_{E_1}\) as follows
# compute the lensed waveform polarizations, strains in the requested detectors and their frequencies
waveform_model.lensed_gw(Img_ra, Img_dec,
.
.
scaled = True,
scale_factor = thetaE1)
# and their signal-to-noise-ratios
waveform_model.lensed_snr(Img_ra, Img_dec,
.
.
scaled = True,
scale_factor = thetaE1)
where omitted lines are unchanged.
User-defined cosmology¶
# time delays, magnifications, Morse indices
TimeDelay(Img_ra, Img_dec,
.
.
cosmo = asropy_cosmo_instance)
# compute the lensed waveform polarizations, strains in the requested detectors and their frequencies
waveform_model.lensed_gw(Img_ra, Img_dec,
.
.
cosmo = asropy_cosmo_instance)
# and their signal-to-noise-ratios
lensed_SNR_dict = waveform_model.lensed_snr(Img_ra, Img_dec,
.
.
cosmo = asropy_cosmo_instance)
where omitted lines are unchanged.
Examples¶
Ready-to-use python
scripts implementing the previous examples: