ler 0.4.2__py3-none-any.whl → 0.4.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ler might be problematic. Click here for more details.
- ler/__init__.py +26 -26
- ler/gw_source_population/__init__.py +1 -0
- ler/gw_source_population/cbc_source_parameter_distribution.py +1073 -815
- ler/gw_source_population/cbc_source_redshift_distribution.py +618 -294
- ler/gw_source_population/jit_functions.py +484 -9
- ler/gw_source_population/sfr_with_time_delay.py +107 -0
- ler/image_properties/image_properties.py +41 -12
- ler/image_properties/multiprocessing_routine.py +5 -209
- ler/lens_galaxy_population/__init__.py +2 -0
- ler/lens_galaxy_population/epl_shear_cross_section.py +0 -0
- ler/lens_galaxy_population/jit_functions.py +101 -9
- ler/lens_galaxy_population/lens_galaxy_parameter_distribution.py +813 -881
- ler/lens_galaxy_population/lens_param_data/density_profile_slope_sl.txt +5000 -0
- ler/lens_galaxy_population/lens_param_data/external_shear_sl.txt +2 -0
- ler/lens_galaxy_population/lens_param_data/number_density_zl_zs.txt +48 -0
- ler/lens_galaxy_population/lens_param_data/optical_depth_epl_shear_vd_ewoud.txt +48 -0
- ler/lens_galaxy_population/mp copy.py +554 -0
- ler/lens_galaxy_population/mp.py +736 -138
- ler/lens_galaxy_population/optical_depth.py +2248 -616
- ler/rates/__init__.py +1 -2
- ler/rates/gwrates.py +126 -72
- ler/rates/ler.py +218 -111
- ler/utils/__init__.py +2 -0
- ler/utils/function_interpolation.py +322 -0
- ler/utils/gwsnr_training_data_generator.py +233 -0
- ler/utils/plots.py +1 -1
- ler/utils/test.py +1078 -0
- ler/utils/utils.py +492 -125
- {ler-0.4.2.dist-info → ler-0.4.3.dist-info}/METADATA +30 -17
- ler-0.4.3.dist-info/RECORD +34 -0
- {ler-0.4.2.dist-info → ler-0.4.3.dist-info}/WHEEL +1 -1
- ler/rates/ler copy.py +0 -2097
- ler-0.4.2.dist-info/RECORD +0 -25
- {ler-0.4.2.dist-info → ler-0.4.3.dist-info/licenses}/LICENSE +0 -0
- {ler-0.4.2.dist-info → ler-0.4.3.dist-info}/top_level.txt +0 -0
|
@@ -120,8 +120,7 @@ class ImageProperties():
|
|
|
120
120
|
z_max=10,
|
|
121
121
|
n_min_images=2,
|
|
122
122
|
n_max_images=4,
|
|
123
|
-
|
|
124
|
-
geocent_time_max=1126259462.4+365*24*3600*20,
|
|
123
|
+
time_window=365*24*3600*20,
|
|
125
124
|
lens_model_list=['EPL_NUMBA', 'SHEAR'],
|
|
126
125
|
cosmology=None,
|
|
127
126
|
spin_zero=True,
|
|
@@ -136,8 +135,9 @@ class ImageProperties():
|
|
|
136
135
|
self.lens_model_list = lens_model_list # list of lens models
|
|
137
136
|
self.spin_zero = spin_zero
|
|
138
137
|
self.spin_precession = spin_precession
|
|
139
|
-
self.
|
|
140
|
-
self.
|
|
138
|
+
self.time_window = time_window
|
|
139
|
+
# self.geocent_time_min = geocent_time_min
|
|
140
|
+
# self.geocent_time_max = geocent_time_max
|
|
141
141
|
self.cosmo = cosmology if cosmology else cosmo
|
|
142
142
|
|
|
143
143
|
# initialize the interpolator's parameters
|
|
@@ -368,15 +368,20 @@ class ImageProperties():
|
|
|
368
368
|
-------
|
|
369
369
|
snrs : `dict`
|
|
370
370
|
signal to noise ratio for each image in each event.
|
|
371
|
-
(dictionary containing 'H1', 'L1', ..., and '
|
|
371
|
+
(dictionary containing 'H1', 'L1', ..., and 'snr_net', which is the network snr, for each image as an array with dimensions (number_of_lensed_events,n_max_images) )
|
|
372
372
|
|
|
373
373
|
"""
|
|
374
374
|
# needed to calculate effective luminosity distance and effective time delay
|
|
375
375
|
n_max_images = self.n_max_images
|
|
376
376
|
magnifications = lensed_param["magnifications"]
|
|
377
377
|
time_delays = lensed_param["time_delays"]
|
|
378
|
+
imgage_type = lensed_param["image_type"]
|
|
378
379
|
size = len(magnifications)
|
|
379
380
|
|
|
381
|
+
# image type to morse phase
|
|
382
|
+
imgage_type[imgage_type==1.] = 0.
|
|
383
|
+
imgage_type[imgage_type==2.] = np.pi/2
|
|
384
|
+
|
|
380
385
|
# Get the binary parameters
|
|
381
386
|
number_of_lensed_events = len(magnifications)
|
|
382
387
|
mass_1, mass_2, theta_jn, psi, ra, dec, phase, a_1, a_2, tilt_1, tilt_2, phi_12, phi_jl = (
|
|
@@ -407,7 +412,7 @@ class ImageProperties():
|
|
|
407
412
|
# setting up snr dictionary
|
|
408
413
|
result_dict = dict()
|
|
409
414
|
if snr_calculator:
|
|
410
|
-
result_dict["
|
|
415
|
+
result_dict["snr_net"] = (
|
|
411
416
|
np.ones((number_of_lensed_events, n_max_images)) * np.nan
|
|
412
417
|
)
|
|
413
418
|
# setting up pdet dictionary
|
|
@@ -445,9 +450,23 @@ class ImageProperties():
|
|
|
445
450
|
time_eff_present = True
|
|
446
451
|
else:
|
|
447
452
|
raise ValueError("geocent_time or effective_geocent_time not given")
|
|
453
|
+
|
|
454
|
+
if "phase" in lensed_param:
|
|
455
|
+
phase = lensed_param["phase"]
|
|
456
|
+
lensed_param["effective_phase"] = np.ones((number_of_lensed_events, n_max_images)) * np.nan
|
|
457
|
+
phase_eff_present = False
|
|
458
|
+
elif "effective_phase" in lensed_param:
|
|
459
|
+
phase_eff = lensed_param["effective_phase"]
|
|
460
|
+
phase_eff_present = True
|
|
461
|
+
else:
|
|
462
|
+
raise ValueError("phase or effective_phase not given")
|
|
463
|
+
|
|
448
464
|
|
|
449
465
|
# Get the optimal signal to noise ratios for each image
|
|
450
466
|
# iterate over the image type (column)
|
|
467
|
+
geocent_time_min = np.min(geocent_time)
|
|
468
|
+
geocent_time_max = geocent_time_min + self.time_window
|
|
469
|
+
|
|
451
470
|
for i in range(n_max_images):
|
|
452
471
|
|
|
453
472
|
# get the effective time for each image type
|
|
@@ -455,8 +474,10 @@ class ImageProperties():
|
|
|
455
474
|
effective_geocent_time = geocent_time + time_delays[:, i]
|
|
456
475
|
else:
|
|
457
476
|
effective_geocent_time = time_eff[:, i]
|
|
477
|
+
|
|
458
478
|
# choose only the events that are within the time range and also not nan
|
|
459
|
-
idx = (effective_geocent_time <=
|
|
479
|
+
idx = (effective_geocent_time <= geocent_time_max) & (effective_geocent_time >= geocent_time_min)
|
|
480
|
+
|
|
460
481
|
# get the effective luminosity distance for each image type
|
|
461
482
|
if not dl_eff_present:
|
|
462
483
|
effective_luminosity_distance = luminosity_distance / np.sqrt(
|
|
@@ -464,12 +485,17 @@ class ImageProperties():
|
|
|
464
485
|
)
|
|
465
486
|
else:
|
|
466
487
|
effective_luminosity_distance = dl_eff[:, i]
|
|
488
|
+
# get the effective phase for each image type
|
|
489
|
+
if not phase_eff_present:
|
|
490
|
+
effective_phase = phase - imgage_type[:, i] # morse phase correction
|
|
491
|
+
else:
|
|
492
|
+
effective_phase = phase_eff[:, i]
|
|
467
493
|
|
|
468
494
|
# check for nan values
|
|
469
|
-
idx = idx & ~np.isnan(effective_luminosity_distance) & ~np.isnan(effective_geocent_time)
|
|
495
|
+
idx = idx & ~np.isnan(effective_luminosity_distance) & ~np.isnan(effective_geocent_time) & ~np.isnan(effective_phase)
|
|
470
496
|
|
|
471
497
|
# Each image has their own effective luminosity distance and effective geocent time
|
|
472
|
-
if
|
|
498
|
+
if sum(idx) != 0:
|
|
473
499
|
# Returns a dictionary
|
|
474
500
|
if snr_calculator:
|
|
475
501
|
optimal_snr = snr_calculator(
|
|
@@ -479,7 +505,7 @@ class ImageProperties():
|
|
|
479
505
|
luminosity_distance=effective_luminosity_distance[idx],
|
|
480
506
|
theta_jn=theta_jn[idx],
|
|
481
507
|
psi=psi[idx],
|
|
482
|
-
phase=
|
|
508
|
+
phase= effective_phase[idx],
|
|
483
509
|
geocent_time=effective_geocent_time[idx],
|
|
484
510
|
ra=ra[idx],
|
|
485
511
|
dec=dec[idx],
|
|
@@ -492,7 +518,7 @@ class ImageProperties():
|
|
|
492
518
|
),
|
|
493
519
|
output_jsonfile=False,
|
|
494
520
|
)
|
|
495
|
-
result_dict["
|
|
521
|
+
result_dict["snr_net"][idx, i] = optimal_snr["snr_net"]
|
|
496
522
|
|
|
497
523
|
if list_of_detectors:
|
|
498
524
|
for detector in list_of_detectors:
|
|
@@ -507,7 +533,7 @@ class ImageProperties():
|
|
|
507
533
|
luminosity_distance=effective_luminosity_distance[idx],
|
|
508
534
|
theta_jn=theta_jn[idx],
|
|
509
535
|
psi=psi[idx],
|
|
510
|
-
phase=
|
|
536
|
+
phase= effective_phase[idx],
|
|
511
537
|
geocent_time=effective_geocent_time[idx],
|
|
512
538
|
ra=ra[idx],
|
|
513
539
|
dec=dec[idx],
|
|
@@ -529,10 +555,13 @@ class ImageProperties():
|
|
|
529
555
|
|
|
530
556
|
lensed_param["effective_luminosity_distance"][:, i] = effective_luminosity_distance
|
|
531
557
|
lensed_param["effective_geocent_time"][:, i] = effective_geocent_time
|
|
558
|
+
lensed_param["effective_phase"][:, i] = effective_phase
|
|
532
559
|
|
|
533
560
|
if dl_eff_present:
|
|
534
561
|
del lensed_param["effective_luminosity_distance"]
|
|
535
562
|
if time_eff_present:
|
|
536
563
|
del lensed_param["effective_geocent_time"]
|
|
564
|
+
if phase_eff_present:
|
|
565
|
+
del lensed_param["effective_phase"]
|
|
537
566
|
|
|
538
567
|
return result_dict, lensed_param
|
|
@@ -7,8 +7,8 @@ import numpy as np
|
|
|
7
7
|
from lenstronomy.LensModel.lens_model import LensModel
|
|
8
8
|
from lenstronomy.LensModel.Solver.lens_equation_solver import LensEquationSolver
|
|
9
9
|
from lenstronomy.LensModel.Solver.epl_shear_solver import caustics_epl_shear
|
|
10
|
-
from lenstronomy.Util.param_util import phi_q2_ellipticity
|
|
11
|
-
from ..lens_galaxy_population.jit_functions import axis_ratio_rayleigh
|
|
10
|
+
# from lenstronomy.Util.param_util import phi_q2_ellipticity
|
|
11
|
+
# from ..lens_galaxy_population.jit_functions import axis_ratio_rayleigh
|
|
12
12
|
|
|
13
13
|
# For sampling from caustic
|
|
14
14
|
from shapely.geometry import Polygon
|
|
@@ -38,7 +38,7 @@ def solve_lens_equation(lens_parameters):
|
|
|
38
38
|
Returns
|
|
39
39
|
-------
|
|
40
40
|
x_source : `float`
|
|
41
|
-
x position of the source in the source plane
|
|
41
|
+
x position of the source in the source plane, unit: arcsec
|
|
42
42
|
y_source : `float`
|
|
43
43
|
y position of the source in the source plane
|
|
44
44
|
x0_image_position : `float`
|
|
@@ -121,7 +121,7 @@ def solve_lens_equation(lens_parameters):
|
|
|
121
121
|
)
|
|
122
122
|
caustic = np.logical_not(np.isnan(caustic_double_points).any())
|
|
123
123
|
|
|
124
|
-
# If there is a nan, caustic=False,
|
|
124
|
+
# If there is a nan, caustic=False, this batch will be ignored and resampled outside in lens_parameters sampling
|
|
125
125
|
if caustic:
|
|
126
126
|
break
|
|
127
127
|
else:
|
|
@@ -139,6 +139,7 @@ def solve_lens_equation(lens_parameters):
|
|
|
139
139
|
iteration,
|
|
140
140
|
)
|
|
141
141
|
|
|
142
|
+
# define region in the source plane where 2 or more images are formed
|
|
142
143
|
caustic_double = Polygon(caustic_double_points.T)
|
|
143
144
|
|
|
144
145
|
# check for strong lensed condition
|
|
@@ -242,208 +243,3 @@ def solve_lens_equation(lens_parameters):
|
|
|
242
243
|
)
|
|
243
244
|
|
|
244
245
|
|
|
245
|
-
# def solve_lens_equation(lens_parameters):
|
|
246
|
-
# """
|
|
247
|
-
# Function to solve the lens equation (min_image = 2)
|
|
248
|
-
|
|
249
|
-
# Parameters
|
|
250
|
-
# ----------
|
|
251
|
-
# lens_parameters : `list`
|
|
252
|
-
# a list of parameters
|
|
253
|
-
# lens_parameters[0] = min_images : minimum number of images
|
|
254
|
-
# lens_parameters[1] = e1 : ellipticity
|
|
255
|
-
# lens_parameters[2] = e2 : ellipticity
|
|
256
|
-
# lens_parameters[3] = gamma : power-law index
|
|
257
|
-
# lens_parameters[4] = gamma1 : shear
|
|
258
|
-
# lens_parameters[5] = gamma2 : shear
|
|
259
|
-
# lens_parameters[6] = zl : redshift of the lens
|
|
260
|
-
# lens_parameters[7] = zs : redshift of the source
|
|
261
|
-
# lens_parameters[8] = einstein_radius : Einstein radius
|
|
262
|
-
# lens_parameters[9] = iteration : iteration number
|
|
263
|
-
# lens_parameters[10:] = lens_model_list : numpy array of lens models
|
|
264
|
-
|
|
265
|
-
# Returns
|
|
266
|
-
# -------
|
|
267
|
-
# x_source : `float`
|
|
268
|
-
# x position of the source in the source plane
|
|
269
|
-
# y_source : `float`
|
|
270
|
-
# y position of the source in the source plane
|
|
271
|
-
# x0_image_position : `float`
|
|
272
|
-
# x position of the images in the source plane
|
|
273
|
-
# x1_image_position : `float`
|
|
274
|
-
# y position of the images in the source plane
|
|
275
|
-
# magnifications : `float`
|
|
276
|
-
# magnification of the images
|
|
277
|
-
# time_delays : `float`
|
|
278
|
-
# time-delay of the images
|
|
279
|
-
# nImages : `int`
|
|
280
|
-
# number of images
|
|
281
|
-
# determinant : `float`
|
|
282
|
-
# determinant of the hessian matrix
|
|
283
|
-
# trace : `float`
|
|
284
|
-
# trace of the hessian matrix
|
|
285
|
-
# iteration : `int`
|
|
286
|
-
# iteration number
|
|
287
|
-
|
|
288
|
-
# Examples
|
|
289
|
-
# --------
|
|
290
|
-
# >>> from ler.multiprocessing_routine import solve_lens_equation1
|
|
291
|
-
# >>> import numpy as np
|
|
292
|
-
# >>> from multiprocessing import Pool
|
|
293
|
-
# >>> # lens parameters input contains 12 parameters [e1, e2, gamma, gamma1, gamma2, zl, zs, einstein_radius, iteration, lens_model_list]
|
|
294
|
-
# >>> lens_parameters1 = np.array([2, 0.024069457093642648, -0.016002190961948142, 1.8945414936459974, 0.10117465203892329, 0.09600089396968613, 0.2503743800068136, 0.9418211055453296, 2.5055790287104725e-06, 0, 'EPL_NUMBA', 'SHEAR'], dtype=object)
|
|
295
|
-
# >>> lens_parameters2 = np.array([2, -0.04030088581646998, -0.01419438113690042, 2.0068239327017, 0.08482718989370612, -0.015393332086560785, 1.0952303138971118, 2.5534097159384417, 1.0125570159563301e-06, 1, 'EPL_NUMBA', 'SHEAR'], dtype=object)
|
|
296
|
-
# >>> input_arguments = np.vstack((lens_parameters1, lens_parameters2))
|
|
297
|
-
# >>> # solve the lens equation for each set of lens parameters
|
|
298
|
-
# >>> with Pool(2) as p:
|
|
299
|
-
# ... result = p.map(solve_lens_equation1, input_arguments)
|
|
300
|
-
# >>> # result is a list of tuples
|
|
301
|
-
# >>> # each tuple contains the output parameters of the function
|
|
302
|
-
# >>> # each output parameter contains x_source, y_source, x0_image_position, x1_image_position, magnifications, time_delays, nImages, determinant, trace, iteration
|
|
303
|
-
# >>> print(f"magnification of images with lens parameters 'lens_parameters1' is {result[0][6]}")
|
|
304
|
-
# magnification of images with lens parameters 'lens_parameters1' is [ 2.18973765 -1.27542831]
|
|
305
|
-
|
|
306
|
-
# """
|
|
307
|
-
# n_min_images = int(lens_parameters[0])
|
|
308
|
-
# zl = lens_parameters[6]
|
|
309
|
-
# zs = lens_parameters[7]
|
|
310
|
-
# einstein_radius = lens_parameters[8]
|
|
311
|
-
# iteration = lens_parameters[9]
|
|
312
|
-
# # lensModel parameters are the same for the three functions used for image param calculation
|
|
313
|
-
# # 1. x-y position of images in the source plane, 2. magnifications, 3. time-delays (relative)
|
|
314
|
-
# lensModel = LensModel(
|
|
315
|
-
# lens_model_list=lens_parameters[10:].tolist(), z_lens=zl, z_source=zs
|
|
316
|
-
# )
|
|
317
|
-
|
|
318
|
-
# lens_eq_solver = LensEquationSolver(lensModel)
|
|
319
|
-
|
|
320
|
-
# factor = 1.0
|
|
321
|
-
# # ---------------------------------------------------#
|
|
322
|
-
# # x-y position of images in the source plane
|
|
323
|
-
# # ---------------------------------------------------#
|
|
324
|
-
# # Get the caustic curve cut by the lens
|
|
325
|
-
# # First check if there is any nan in the caustic points
|
|
326
|
-
# def check_caustic():
|
|
327
|
-
# """
|
|
328
|
-
# Function to check if there is any nan in the caustic points
|
|
329
|
-
# """
|
|
330
|
-
# while True:
|
|
331
|
-
# kwargs_lens = [
|
|
332
|
-
# {
|
|
333
|
-
# "theta_E": factor,
|
|
334
|
-
# "e1": lens_parameters[1],
|
|
335
|
-
# "e2": lens_parameters[2],
|
|
336
|
-
# "gamma": lens_parameters[3],
|
|
337
|
-
# "center_x": 0.0,
|
|
338
|
-
# "center_y": 0.0,
|
|
339
|
-
# },
|
|
340
|
-
# {
|
|
341
|
-
# "gamma1": lens_parameters[4],
|
|
342
|
-
# "gamma2": lens_parameters[5],
|
|
343
|
-
# "ra_0": 0,
|
|
344
|
-
# "dec_0": 0,
|
|
345
|
-
# },
|
|
346
|
-
# ]
|
|
347
|
-
# caustic_double_points = caustics_epl_shear(
|
|
348
|
-
# kwargs_lens, return_which="double", maginf=-100
|
|
349
|
-
# )
|
|
350
|
-
# caustic = np.logical_not(np.isnan(caustic_double_points).any())
|
|
351
|
-
|
|
352
|
-
# # If there is a nan, caustic=False, draw a new gamma
|
|
353
|
-
# if caustic:
|
|
354
|
-
# break
|
|
355
|
-
# else:
|
|
356
|
-
# #
|
|
357
|
-
# q = axis_ratio_rayleigh(sigma=np.array([160.]))[0]
|
|
358
|
-
# phi = np.random.uniform(0.0, 2*np.pi, size=1)[0]
|
|
359
|
-
# lens_parameters[1], lens_parameters[2] = phi_q2_ellipticity(phi, q)
|
|
360
|
-
# # resampling power-law index and shear
|
|
361
|
-
# lens_parameters[3] = np.random.normal(loc=2.0, scale=0.2, size=1)[0]
|
|
362
|
-
# gamma1, gamma2 = np.random.normal(loc=0, scale=0.05,size=(2,1))
|
|
363
|
-
# lens_parameters[4], lens_parameters[5] = gamma1[0], gamma2[0]
|
|
364
|
-
|
|
365
|
-
# caustic_double = Polygon(caustic_double_points.T)
|
|
366
|
-
# return caustic_double, kwargs_lens
|
|
367
|
-
|
|
368
|
-
# caustic_double, kwargs_lens = check_caustic()
|
|
369
|
-
|
|
370
|
-
# # check for strong lensed condition
|
|
371
|
-
# strongly_lensed = False
|
|
372
|
-
# i = 0
|
|
373
|
-
# while strongly_lensed == False:
|
|
374
|
-
# # Draw random points within the caustic
|
|
375
|
-
# # sometimes x_source, y_source positions are at same location and the solver fails
|
|
376
|
-
# # so we use a try-except block to catch the error and draw a new point
|
|
377
|
-
# # try:
|
|
378
|
-
# x_source, y_source = pointpats.random.poisson(caustic_double, size=1)
|
|
379
|
-
# # Solve the lens equation
|
|
380
|
-
# (
|
|
381
|
-
# x0_image_position,
|
|
382
|
-
# x1_image_position,
|
|
383
|
-
# ) = lens_eq_solver.image_position_from_source(
|
|
384
|
-
# sourcePos_x=x_source,
|
|
385
|
-
# sourcePos_y=y_source,
|
|
386
|
-
# kwargs_lens=kwargs_lens,
|
|
387
|
-
# solver="analytical",
|
|
388
|
-
# magnification_limit=1.0 / 1000.0,
|
|
389
|
-
# arrival_time_sort=True,
|
|
390
|
-
# )
|
|
391
|
-
# nImages = len(x0_image_position) # shows how many images
|
|
392
|
-
# if nImages >= n_min_images:
|
|
393
|
-
# strongly_lensed = True
|
|
394
|
-
# # except:
|
|
395
|
-
# # pass
|
|
396
|
-
# ## test ##
|
|
397
|
-
# if i > 10:
|
|
398
|
-
# print("Could not find a valid source position. Run the sampling again by setting resume=True")
|
|
399
|
-
# caustic_double, kwargs_lens = check_caustic()
|
|
400
|
-
# i = 0
|
|
401
|
-
# i += 1
|
|
402
|
-
# ##########
|
|
403
|
-
|
|
404
|
-
# # ---------------------------------------------------#
|
|
405
|
-
# # magnification and time-delay
|
|
406
|
-
# # ---------------------------------------------------#
|
|
407
|
-
# # theta_E is in arcsec
|
|
408
|
-
# theta_E_nImages = einstein_radius * np.ones(nImages)
|
|
409
|
-
# radian_to_arcseconds = 180.0 / np.pi * 3600.0
|
|
410
|
-
# days_to_seconds = 24.0 * 3600.0
|
|
411
|
-
# # can have multiple magnification
|
|
412
|
-
# magnifications = lensModel.magnification(
|
|
413
|
-
# x0_image_position, x1_image_position, kwargs_lens
|
|
414
|
-
# )
|
|
415
|
-
# time_delays = (
|
|
416
|
-
# lensModel.arrival_time(x0_image_position, x1_image_position, kwargs_lens)
|
|
417
|
-
# * (theta_E_nImages * radian_to_arcseconds) ** 2
|
|
418
|
-
# * days_to_seconds
|
|
419
|
-
# )
|
|
420
|
-
|
|
421
|
-
# # ---------------------------------------------------#
|
|
422
|
-
# # Params needed for image-type classification
|
|
423
|
-
# # ---------------------------------------------------#
|
|
424
|
-
# # it is faster to use numpy array operation to do image classification
|
|
425
|
-
# # return: f_xx, f_xy, f_yx, f_yy components
|
|
426
|
-
# hessian = lensModel.hessian(x0_image_position, x1_image_position, kwargs_lens)
|
|
427
|
-
# determinant = np.array(
|
|
428
|
-
# (1 - hessian[0]) * (1 - hessian[3]) - hessian[1] * hessian[2]
|
|
429
|
-
# )
|
|
430
|
-
# trace = np.array(2 - hessian[0] - hessian[3])
|
|
431
|
-
|
|
432
|
-
# # return also gamma1, gamma2
|
|
433
|
-
# return (
|
|
434
|
-
# x_source,
|
|
435
|
-
# y_source,
|
|
436
|
-
# x0_image_position,
|
|
437
|
-
# x1_image_position,
|
|
438
|
-
# magnifications,
|
|
439
|
-
# time_delays,
|
|
440
|
-
# nImages,
|
|
441
|
-
# determinant,
|
|
442
|
-
# trace,
|
|
443
|
-
# lens_parameters[1],
|
|
444
|
-
# lens_parameters[2],
|
|
445
|
-
# lens_parameters[3],
|
|
446
|
-
# lens_parameters[4],
|
|
447
|
-
# lens_parameters[5],
|
|
448
|
-
# iteration,
|
|
449
|
-
# )
|
|
File without changes
|
|
@@ -68,9 +68,10 @@ def pdf_phi_z_div_0(s, z):
|
|
|
68
68
|
return phi_sim_z / phi_sim_0
|
|
69
69
|
|
|
70
70
|
@njit
|
|
71
|
-
def phi(s,z,
|
|
71
|
+
def phi(s, z, alpha=0.94, beta=1.85, phistar=2.099e-2, sigmastar=113.78):
|
|
72
72
|
"""
|
|
73
73
|
Function to calculate the lens galaxy velocity dispersion function at redshift z.
|
|
74
|
+
For Oguri et al. (2018b) model: alpha=0.94, beta=1.85, phistar=2.099e-2*(self.cosmo.h/0.7)**3, sigmastar=113.78
|
|
74
75
|
|
|
75
76
|
Parameters
|
|
76
77
|
----------
|
|
@@ -85,15 +86,17 @@ def phi(s,z, cosmology_h=0.7):
|
|
|
85
86
|
-------
|
|
86
87
|
result : `float: array`
|
|
87
88
|
"""
|
|
88
|
-
|
|
89
|
-
result =
|
|
90
|
-
|
|
89
|
+
|
|
90
|
+
result = pdf_phi_z_div_0(s,z) * phi_loc_bernardi(sigma=s, alpha=alpha, beta=beta, phistar=phistar, sigmastar=sigmastar)
|
|
91
|
+
result[result < 0.] = 0.
|
|
91
92
|
return result
|
|
92
93
|
|
|
93
94
|
@njit
|
|
94
|
-
def phi_loc_bernardi(sigma, alpha
|
|
95
|
+
def phi_loc_bernardi(sigma, alpha, beta, phistar, sigmastar):
|
|
95
96
|
"""
|
|
96
97
|
Function to calculate the local universe velocity dispersion function. Bernardi et al. (2010).
|
|
98
|
+
For Oguri et al. (2018b) model: alpha=0.94, beta=1.85, phistar=2.099e-2*(self.cosmo.h/0.7)**3, sigmastar=113.78
|
|
99
|
+
For Choi et al. (2008) model: alpha = 2.32 / 2.67, beta = 2.67, phistar = 8.0e-3*self.cosmo.h**3, sigmastar = 161.0
|
|
97
100
|
|
|
98
101
|
Parameters
|
|
99
102
|
----------
|
|
@@ -109,7 +112,7 @@ def phi_loc_bernardi(sigma, alpha=0.94, beta=1.85, phistar=2.099e-2, sigmastar=1
|
|
|
109
112
|
philoc_ : `float: array`
|
|
110
113
|
"""
|
|
111
114
|
|
|
112
|
-
phistar = phistar * (cosmology_h / 0.7) ** 3 # Mpc**-3
|
|
115
|
+
# phistar = phistar * (cosmology_h / 0.7) ** 3 # Mpc**-3
|
|
113
116
|
philoc_ = phistar*(sigma/sigmastar)**alpha * np.exp(-(sigma/sigmastar)**beta) * beta/gamma_(alpha/beta)/sigma
|
|
114
117
|
return philoc_
|
|
115
118
|
|
|
@@ -143,7 +146,7 @@ def phi_cut_SIE(q):
|
|
|
143
146
|
return result/np.pi
|
|
144
147
|
|
|
145
148
|
@njit
|
|
146
|
-
def
|
|
149
|
+
def axis_ratio_rayleigh_rvs(sigma, q_min=0.2, q_max=1.0):
|
|
147
150
|
"""
|
|
148
151
|
Function to sample axis ratio from rayleigh distribution with given velocity dispersion.
|
|
149
152
|
|
|
@@ -184,6 +187,16 @@ def axis_ratio_rayleigh(sigma, q_min=0.2, q_max=1.0):
|
|
|
184
187
|
|
|
185
188
|
return q
|
|
186
189
|
|
|
190
|
+
@njit
|
|
191
|
+
def axis_ratio_rayleigh_pdf(q, sigma, q_min=0.2, q_max=1.0):
|
|
192
|
+
|
|
193
|
+
s = 0.38 - 5.7e-4 * sigma
|
|
194
|
+
idx = (q >= q_min) & (q <= q_max)
|
|
195
|
+
q_pdf = np.zeros_like(q)
|
|
196
|
+
q_pdf[idx] = (1-q[idx])/s[idx]**2 * np.exp(-0.5*(1-q[idx])**2/s[idx]**2)
|
|
197
|
+
return q_pdf
|
|
198
|
+
|
|
199
|
+
|
|
187
200
|
@njit
|
|
188
201
|
def velocity_dispersion_z_dependent(size, zl, zl_list, vd_inv_cdf):
|
|
189
202
|
"""
|
|
@@ -215,9 +228,9 @@ def velocity_dispersion_z_dependent(size, zl, zl_list, vd_inv_cdf):
|
|
|
215
228
|
return samples
|
|
216
229
|
|
|
217
230
|
@njit
|
|
218
|
-
def
|
|
231
|
+
def lens_redshift_SDSS_catalogue_sis(zs, splineDc, splineDcInv, u, cdf):
|
|
219
232
|
"""
|
|
220
|
-
Function to sample lens redshift from the SDSS catalogue.
|
|
233
|
+
Function to sample lens redshift from the SDSS catalogue. Haris et al. (2018) cdf = (10 * u**3 - 15 * u**4 + 6 * u**5)
|
|
221
234
|
|
|
222
235
|
Parameters
|
|
223
236
|
----------
|
|
@@ -275,4 +288,83 @@ def bounded_normal_sample(size, mean, std, low, high):
|
|
|
275
288
|
samples[i] = sample
|
|
276
289
|
return samples
|
|
277
290
|
|
|
291
|
+
|
|
292
|
+
@njit
|
|
293
|
+
def phi_q2_ellipticity_hemanta(phi, q):
|
|
294
|
+
"""Function to convert phi and q to ellipticity e1 and e2.
|
|
295
|
+
|
|
296
|
+
Parameters
|
|
297
|
+
----------
|
|
298
|
+
phi : `float: array`
|
|
299
|
+
angle of the major axis in radians
|
|
300
|
+
q : `float: array`
|
|
301
|
+
axis ratio
|
|
302
|
+
|
|
303
|
+
Returns
|
|
304
|
+
-------
|
|
305
|
+
e1 : `float: array`
|
|
306
|
+
ellipticity component 1
|
|
307
|
+
e2 : `float: array`
|
|
308
|
+
"""
|
|
309
|
+
|
|
310
|
+
e_1 = (1.0 - q) / (1.0 + q) * np.cos(2 * phi)
|
|
311
|
+
e_2 = (1.0 - q) / (1.0 + q) * np.sin(2 * phi)
|
|
312
|
+
return e_1, e_2
|
|
313
|
+
|
|
314
|
+
# @njit
|
|
315
|
+
# def sample_sigma_zl(pdf, sigma_min, sigma_max, zl_min, zl_max, zs, chunk_size=10000):
|
|
316
|
+
# x_sample = []
|
|
317
|
+
# y_sample = []
|
|
278
318
|
|
|
319
|
+
# for z in zs:
|
|
320
|
+
# xmin, xmax = sigma_min, sigma_max
|
|
321
|
+
# ymin, ymax = zl_min, z
|
|
322
|
+
|
|
323
|
+
# # Keep sampling until a valid (sigma, zl) pair is found for this z
|
|
324
|
+
# while True:
|
|
325
|
+
# x_try = np.random.uniform(xmin, xmax, chunk_size)
|
|
326
|
+
# y_try = np.random.uniform(ymin, ymax, chunk_size)
|
|
327
|
+
# pdf_xy_try = pdf(x_try, y_try)
|
|
328
|
+
# zmax = np.max(pdf_xy_try) # Maximum of the PDF for the current batch
|
|
329
|
+
|
|
330
|
+
# # Generate acceptance thresholds
|
|
331
|
+
# z_try = np.random.uniform(0, zmax, chunk_size)
|
|
332
|
+
|
|
333
|
+
# # Check which samples are accepted
|
|
334
|
+
# accepted_indices = z_try < pdf_xy_try
|
|
335
|
+
# if np.any(accepted_indices):
|
|
336
|
+
# # Accept the first valid sample
|
|
337
|
+
# x_sample.append(x_try[accepted_indices][0])
|
|
338
|
+
# y_sample.append(y_try[accepted_indices][0])
|
|
339
|
+
# break # Exit the loop once the first valid sample is collected
|
|
340
|
+
|
|
341
|
+
# return np.array(x_sample), np.array(y_sample)
|
|
342
|
+
|
|
343
|
+
@njit
|
|
344
|
+
def sample_sigma_zl(pdf, sigma_min, sigma_max, zl_min, zl_max, zs, chunk_size=10000):
|
|
345
|
+
x_sample = []
|
|
346
|
+
y_sample = []
|
|
347
|
+
|
|
348
|
+
for z in zs:
|
|
349
|
+
xmin, xmax = sigma_min, sigma_max
|
|
350
|
+
ymin, ymax = zl_min, zl_max # Use full range and then filter
|
|
351
|
+
|
|
352
|
+
valid_sample_found = False
|
|
353
|
+
while not valid_sample_found:
|
|
354
|
+
x_try = np.random.uniform(xmin, xmax, chunk_size)
|
|
355
|
+
y_try = np.random.uniform(ymin, ymax, chunk_size)
|
|
356
|
+
pdf_xy_try = pdf(x_try, y_try)
|
|
357
|
+
zmax = np.max(pdf_xy_try) # Find maximum PDF value for current batch
|
|
358
|
+
|
|
359
|
+
# Generate acceptance thresholds
|
|
360
|
+
z_try = np.random.uniform(0, zmax, chunk_size)
|
|
361
|
+
|
|
362
|
+
# Check and accept samples
|
|
363
|
+
accepted = (z_try < pdf_xy_try) & (y_try < z) # Ensure zl < zs condition
|
|
364
|
+
if np.any(accepted):
|
|
365
|
+
idx = np.argmax(accepted) # First valid index
|
|
366
|
+
x_sample.append(x_try[idx])
|
|
367
|
+
y_sample.append(y_try[idx])
|
|
368
|
+
valid_sample_found = True
|
|
369
|
+
|
|
370
|
+
return np.array(x_sample), np.array(y_sample)
|