def run(outidx, identifier, zlens, zsrc, log_m_break): pyhalo = pyHalo(zlens, zsrc) lens_params = {'R_ein': 1.2, 'x': 0, 'y': 0, 'ellip': 0.22, 'ellip_theta': 23, 'shear': 0.06, 'shear_theta': -40, 'gamma': 2} start = Deflector(redshift=zlens, subclass=SIE(), varyflags=['1', '1', '1', '1', '1', '1', '1', '0', '0', '0'], **lens_params) solver = SolveRoutines(zlens, zsrc) multiplane = True init_args = {'mdef_main': 'TNFW', 'mdef_los': 'TNFW', 'log_mlow': 6, 'log_mhigh': 10, 'power_law_index': -1.9, 'parent_m200': 10 ** 13, 'parent_c': 3, 'mdef': 'TNFW', 'break_index': -1.3, 'c_scale': 60, 'c_power': -0.17, 'r_tidal': '0.4Rs', 'break_index': -1.3, 'c_scale': 60, 'c_power': -0.17, 'cone_opening_angle': 6} model_args_CDM = init_args model_args_CDM.update({'fsub': 0.01, 'log_m_break': log_m_break}) halos = pyhalo.render('composite_powerlaw', model_args_CDM) dtofit = solver.solve_lens_equation(macromodel=start, realizations=None, multiplane=multiplane, srcx=-0.085, srcy=0.13, polar_grid=False, source_size_kpc=0.05, brightimg=True) opt_full, mod_full, info = solver.hierarchical_optimization(macromodel=start, datatofit=dtofit[0], realizations=halos, multiplane=True, n_particles=20, n_iterations=350, verbose=True, re_optimize=True, restart=1, particle_swarm=True, pso_convergence_mean=20000, pso_compute_magnification=500, source_size_kpc=0.05, simplex_n_iter=400, grid_res=0.0025, LOS_mass_sheet=7.7) relative_paths(info, zlens, identifier, outidx)
def ULDM(z_lens, z_source, log10_m_uldm, log10_fluc_amplitude=-1.5, velocity_scale=200, log_mlow=6., log_mhigh=10., b_uldm=1.1, c_uldm=-2.2, c_scale=15., c_power=-0.3, cone_opening_angle_arcsec=6., sigma_sub=0.025, LOS_normalization=1., log_m_host=13.3, power_law_index=-1.9, r_tidal='0.25Rs', mass_definition='ULDM', uldm_plaw=1 / 3, scale_nfw=False, flucs=True, flucs_shape='aperture', flucs_args={}, einstein_radius=6., n_cut=5e4, **kwargs_other): """ This generates realizations of ultra-light dark matter (ULDM), including the ULDM halo mass function and halo density profiles, as well as density fluctuations in the main deflector halo. Similarly to WDMGeneral, the functional form of the subhalo mass function is the same as the field halo mass function. However, this model differs from WDMGeneral by creating halos which are composite ULDM + NFW density profiles. The ULDM particle mass and core radius-halo mass power law exponent must now be specified. For details regarding ULDM halos, see Schive et al. 2014 (https://arxiv.org/pdf/1407.7762.pdf). Equations (3) and (7) give the soliton density profile and core radius, respectively. The differential halo mass function is described by three parameters, see Schive et al. 2016 (https://arxiv.org/pdf/1508.04621.pdf): 1) log_m0 - the log10 value of the characteristic mass, or the scale where the ULDM mass function begins to deviate from CDM: m0 = (1.6*10**10) * (m22)**(-4/3) [solar masses], where m22 = m_uldm / 10**22 eV. 2) b_uldm - modifies the log slope of the ULDM mass function, analogous to b_wdm (see WDMLovell2020) 3) c_uldm - modifies the log slope of the ULDM mass function, analogous to c_wdm (see WDMLovell2020) The parametrization for the mass function is: n_uldm / n_cdm = (1 + (m / m_0)^b_uldm) ^ c_uldm, where Schive et al. 2016 determined that (m_0, b_uldm, c_uldm) = ( (1.6*10**10) * (m22)**(-4/3), 1.1, 2.2) As for the concentration relative to CDM, Du et al. 2016 (https://arxiv.org/pdf/1608.02575.pdf) found that the same fitting function as Lovell 2020 is a good estimation of the ULDM concentration, i.e. simply c_wdm = c_uldm, with (c_scale, c_power) = (15, -0.3). Furthermore, Schive et al. 2014 (https://arxiv.org/pdf/1407.7762.pdf) found a redshift-dependent minimum ULDM halo mass given by M_min(z) = a^(-3/4) * (Zeta(z)/Zeta(0))^(1/4) * M_min,0 [solar masses] where a is the cosmic scale factor, M_min,0 = 4.4*10^7 * m22^(-3/2) [solar masses] and Zeta(z) = (18*pi^2 + 82(Om(z) - 1) - 39(Om(z) - 1)^2) / Om(z), where Om(z) is the matter density parameter. :param z_lens: the lens redshift :param z_source: the source redshift :param log10_m_uldm: ULDM particle mass in log units, typically 1e-22 eV :param log10_fluc_amplitude: sets the amplitude of the fluctuations in the host dark matter halo. fluctuations are generated from a Guassian distriubtion with mean 0 and variance 10^log10_fluc_amplitude :param velocity_scale: velocity for de Broglie wavelength calculation in km/s :param log_mhigh: log10(maximum halo mass) rendered (mass definition is M200 w.r.t. critical density) :param b_uldm: defines the ULDM mass function (see above) :param c_uldm: defines the ULDM mass function (see above) :param c_scale: scale where concentrations in ULDM deviate from CDM (see WDMLovell2020) :param c_power: modification to logarithmic slope of mass-concentration relation (see WDMLovell2020) :param cone_opening_angle: the opening angle in arcsec of the double cone geometry where halos are added :param sigma_sub: normalization of the subhalo mass function (see description in CDM preset model) :param LOS_normalization: rescaling of the line of sight halo mass function relative to Sheth-Tormen :param log_m_host: log10 host halo mass in M_sun :param power_law_index: logarithmic slope of the subhalo mass function :param r_tidal: subhalos are distributed following a cored NFW profile with a core radius r_tidal. This is intended to account for tidal stripping of halos that pass close to the central galaxy :param mass_definition: mass profile model for halos :param uldm_plaw: ULDM core radius-halo mass power law exponent, typically 1/3 :param scale_nfw: boolean specifiying whether or not to scale the NFW component (can improve mass accuracy) :param flucs: Boolean specifying whether or not to include density fluctuations in the main deflector halo :param flucs_shape: String specifying how to place fluctuations, see docs in realization_extensions.add_ULDM_fluctuations :param fluc_args: Keyword arguments for specifying the fluctuations, see docs in realization_extensions.add_ULDM_fluctuations :param einstein_radius: Einstein radius of main deflector halo in kpc :param n_cut: Number of fluctuations above which to start cancelling :param kwargs_other: any other optional keyword arguments :return: a realization of ULDM halos """ # constants m22 = 10**(log10_m_uldm + 22) log_m0 = np.log10(1.6e10 * m22**(-4 / 3)) M_min0 = 4.4e7 * m22**(-3 / 2) # M_solar a_uldm = 1 # set to unity since Schive et al. 2016 do not have an analogous parameter #compute M_min as described in documentation a = lambda z: (1 + z)**(-1) O_m = lambda z: Cosmology().astropy.Om(z) zeta = lambda z: (18 * np.pi**2 + 82 * (O_m(z) - 1) - 39 * (O_m(z) - 1)**2) / O_m(z) m_min = lambda z: a(z)**(-3 / 4) * (zeta(z) / zeta(0))**(1 / 4) * M_min0 log_m_min = lambda z: np.log10(m_min(z)) if log_m_min(z_lens) >= log_mlow: log_mlow = log_m_min( z_lens ) # only use M_min for minimum halo mass if it is above input 'log_mlow' kwargs_model_field = { 'a_wdm': a_uldm, 'b_wdm': b_uldm, 'c_wdm': c_uldm, 'log_mc': log_m0, 'c_scale': c_scale, 'c_power': c_power, 'log_mlow': log_mlow, 'log_mhigh': log_mhigh, 'cone_opening_angle': cone_opening_angle_arcsec, 'mdef_los': mass_definition, 'mass_func_type': 'POWER_LAW', 'LOS_normalization': LOS_normalization, 'log_m_host': log_m_host } kwargs_model_subhalos = { 'a_wdm': a_uldm, 'b_wdm': b_uldm, 'c_wdm': c_uldm, 'log_mc': log_m0, 'c_scale': c_scale, 'c_power': c_power, 'log_mlow': log_mlow, 'log_mhigh': log_mhigh, 'cone_opening_angle': cone_opening_angle_arcsec, 'sigma_sub': sigma_sub, 'mdef_subs': mass_definition, 'mass_func_type': 'POWER_LAW', 'power_law_index': power_law_index, 'r_tidal': r_tidal } kwargs_uldm = { 'log10_m_uldm': log10_m_uldm, 'uldm_plaw': uldm_plaw, 'scale_nfw': scale_nfw } kwargs_model_field.update(kwargs_uldm) kwargs_model_subhalos.update(kwargs_uldm) kwargs_model_field.update(kwargs_other) kwargs_model_subhalos.update(kwargs_other) # this will use the default cosmology. parameters can be found in defaults.py pyhalo = pyHalo(z_lens, z_source) # Using the render method will result a list of realizations realization_subs = pyhalo.render(['SUBHALOS'], kwargs_model_subhalos, nrealizations=1)[0] realization_line_of_sight = pyhalo.render(['LINE_OF_SIGHT', 'TWO_HALO'], kwargs_model_field, nrealizations=1)[0] uldm_realization = realization_line_of_sight.join( realization_subs, join_rendering_classes=True) if flucs: # add fluctuations to realization ext = RealizationExtensions(uldm_realization) lambda_dB = de_broglie_wavelength( log10_m_uldm, velocity_scale) # de Broglie wavelength in kpc if flucs_args == {}: raise Exception( 'Must specify fluctuation arguments, see realization_extensions.add_ULDM_fluctuations' ) fluctuation_amplitude_norm = 10**log10_fluc_amplitude fluctuation_amplitude = fluctuation_amplitude_norm * ( 10**log10_m_uldm / 1e-22)**-0.5 uldm_realization = ext.add_ULDM_fluctuations( de_Broglie_wavelength=lambda_dB, fluctuation_amplitude_variance=fluctuation_amplitude, fluctuation_size_variance=lambda_dB, shape=flucs_shape, args=flucs_args, n_cut=n_cut) return uldm_realization
def CDM(z_lens, z_source, sigma_sub=0.025, shmf_log_slope=-1.9, cone_opening_angle_arcsec=6., log_mlow=6., log_mhigh=10., LOS_normalization=1., log_m_host=13.3, r_tidal='0.25Rs', mass_definition='TNFW', c0=None, log10c0=None, beta=None, zeta=None, **kwargs_other): """ This specifies the keywords for a CDM halo mass function model with a subhalo mass function described by a power law and a line of sight halo mass function described by Sheth-Tormen. The subhalo mass function is parameterized as d^N / dmdA = shmf_norm / m0 * (m/m0)^power_law_index * F(M_host, z) with a pivot mass m0=10^8. In this parameterization, shmf_norm has units of 1/area, or kpc^-2. CDM prediction is something like 0.01 - 0.05, but this depends on the efficiency of stripping and what objects around the host halo you consider a subhalos (are splashback halos subhalos?). The function F(M_host, z) factors the evolution of the projected number density of subhalos with host halo mass and redshift out of the projected number density, so sigma_sub should be common to each host halo. The function F(M_host, z) is calibrated with the semi-analytic modeling tool galacticus (https://arxiv.org/pdf/1008.1786.pdf): F(M_host, z) = a * log10(M_host / 10^13) + b * (1+z) with a = 0.88 and b = 1.7. :param z_lens: main deflector redshift :param z_source: sourcee redshift :param sigma_sub: normalization of the subhalo mass function :param shmf_log_slope: logarithmic slope of the subhalo mass function :param cone_opening_angle_arcsec: the opening angle of the double cone rendering volume in arcsec :param log_mlow: log10(minimum halo mass) rendered, or a function that returns log_mlow given a redshift :param log_mhigh: log10(maximum halo mass) rendered, or a function that returns log_mlow given a redshift :param LOS_normalization: rescaling of the line of sight halo mass function relative to Sheth-Tormen :param log_m_host: log10 host halo mass in M_sun :param r_tidal: subhalos are distributed following a cored NFW profile with a core radius r_tidal. This is intended to account for tidal stripping of halos that pass close to the central galaxy :param kwargs_other: allows for additional keyword arguments to be specified when creating realization :param mass_definition: mass profile model for halos (TNFW is truncated NFW) The following optional keywords specify a concentration-mass relation parameterized as a power law in peak height. If they are not set in the function call, pyHalo assumes a default concentration-mass relation from Diemer&Joyce :param c0: amplitude of the mass-concentration relation at 10^8 :param log10c0: logarithmic amplitude of the mass-concentration relation at 10^8 (only if c0_mcrelation is None) :param beta: logarithmic slope of the mass-concentration-relation pivoting around 10^8 :param zeta: modifies the redshift evolution of the mass-concentration-relation :return: a realization of CDM halos """ kwargs_model_field = { 'cone_opening_angle': cone_opening_angle_arcsec, 'mdef_los': mass_definition, 'mass_func_type': 'POWER_LAW', 'log_mlow': log_mlow, 'log_mhigh': log_mhigh, 'LOS_normalization': LOS_normalization, 'log_m_host': log_m_host } kwargs_model_subhalos = { 'cone_opening_angle': cone_opening_angle_arcsec, 'sigma_sub': sigma_sub, 'power_law_index': shmf_log_slope, 'log_mlow': log_mlow, 'log_mhigh': log_mhigh, 'mdef_subs': mass_definition, 'mass_func_type': 'POWER_LAW', 'r_tidal': r_tidal } if any(x is not None for x in [c0, log10c0, beta, zeta]): if c0 is None: assert log10c0 is not None c0 = 10**log10c0 assert beta is not None assert zeta is not None mc_model = {'custom': True, 'c0': c0, 'beta': beta, 'zeta': zeta} kwargs_mc_relation = {'mc_model': mc_model} kwargs_model_field.update(kwargs_mc_relation) kwargs_model_subhalos.update(kwargs_mc_relation) kwargs_model_field.update(kwargs_other) kwargs_model_subhalos.update(kwargs_other) # this will use the default cosmology. parameters can be found in defaults.py pyhalo = pyHalo(z_lens, z_source) # Using the render method will result a list of realizations realization_subs = pyhalo.render(['SUBHALOS'], kwargs_model_subhalos, nrealizations=1)[0] realization_line_of_sight = pyhalo.render(['LINE_OF_SIGHT', 'TWO_HALO'], kwargs_model_field, nrealizations=1)[0] cdm_realization = realization_line_of_sight.join( realization_subs, join_rendering_classes=True) return cdm_realization
def WDM(z_lens, z_source, log_mc, log_mlow=6., log_mhigh=10., a_wdm_los=2.3, b_wdm_los=0.8, c_wdm_los=-1., a_wdm_sub=4.2, b_wdm_sub=2.5, c_wdm_sub=-0.2, cone_opening_angle_arcsec=6., sigma_sub=0.025, LOS_normalization=1., log_m_host=13.3, power_law_index=-1.9, r_tidal='0.25Rs', kwargs_suppression_field=None, suppression_model_field=None, kwargs_suppression_sub=None, suppression_model_sub=None, **kwargs_other): """ This specifies the keywords for the Warm Dark Matter (WDM) halo mass function model presented by Lovell 2020 (https://arxiv.org/pdf/2003.01125.pdf) The differential halo mass function is described by four parameters: 1) log_mc - the log10 value of the half-mode mass, or the scale where the WDM mass function begins to deviate from CDM 2) a_wdm - scale factor for the characteristic mass scale (see below) 3) b_wdm - modifies the logarithmic slope of the WDM mass function (see below) 4) c_wdm - modifies the logarithmic slope of the WDM mass function (see below) The defult parameterization for the mass function is: n_wdm / n_cdm = (1 + (a_wdm * m_c / m)^b_wdm) ^ c_wdm where m_c = 10**log_mc is the half-mode mass, and n_wdm and n_cdm are differential halo mass functions. Lovell 2020 find different fits to subhalos and field halos. For field halos, (a_wdm, b_wdm, c_wdm) = (2.3, 0.8, -1) while for subhalos (a_wdm_sub, b_wdm_sub, c_wdm_sub) = (4.2, 2.5, -0.2). WDM models also have reduced concentrations relative to CDM halos because WDM structure collapse later, when the Universe is less dense. The default suppresion to halo concentrations is implemented using the fitting function (Eqn. 17) presented by Bose et al. (2016) (https://arxiv.org/pdf/1507.01998.pdf), where the concentration relative to CDM is given by c_wdm / c_cdm = (1+z)^B(z) * (1 + c_scale * m_c / m) ^ c_power where m_c is the same as the definition for the halo mass function and (c_scale, c_power) = (60, -0.17). Note that the factor of 60 makes the effect on halo concentrations kick in on mass scales > m_c. This routine assumes the a mass-concentration for CDM halos given by Diemer & Joyce 2019 (https://arxiv.org/pdf/1809.07326.pdf) :param z_lens: the lens redshift :param z_source: the source redshift :param log_mc: log10(half mode mass) in units M_sun (no little h) :param log_mlow: log10(minimum halo mass) rendered, or a function that returns log_mlow given a redshift :param log_mhigh: log10(maximum halo mass) rendered, or a function that returns log_mlow given a redshift :param a_wdm_los: describes the line of sight WDM halo mass function (see above) :param b_wdm_los: describes the line of sight WDM halo mass function (see above) :param c_wdm_los: describes the line of sight WDM halo mass function (see above) :param a_wdm_sub: defines the WDM subhalo mass function (see above) :param b_wdm_sub: defines the WDM subhalo mass function (see above) :param c_wdm_sub: defines the WDM subhalo mass function (see above) :param cone_opening_angle: the opening angle in arcsec of the volume where halos are added :param sigma_sub: normalization of the subhalo mass function (see description in CDM preset model) :param LOS_normalization: rescaling of the line of sight halo mass function relative to Sheth-Tormen :param log_m_host: log10 host halo mass in M_sun :param power_law_index: logarithmic slope of the subhalo mass function :param r_tidal: subhalos are distributed following a cored NFW profile with a core radius r_tidal. This is intended to account for tidal stripping of halos that pass close to the central galaxy ################################################################################################### The following keywords define how the WDM mass-concentration relation is suppressed relative to CDM :param kwargs_suppression_field: keyword arguments for the suppression function for field halo concentrations :param suppression_model_field: the type of suppression, either 'polynomial' or 'hyperbolic'. Default form is polynomial :param kwargs_suppression_sub: keyword arguments for the suppression function for subhalos :param suppression_model_sub: the type of suppression, either 'polynomial' or 'hyperbolic' The form of the polynomial suppression function, f, is defined in terms of x = half-mode-mass / mass: f = (1 + a * x ^ b_wdm) ^ c_wdm The form of the hyperbolic suppression function, f, is (see functions in Halos.HaloModels.concentration) f = 1/2 [1 + tanh( (x - a_wdm)/2b_wdm ) ) ] ################################################################################################### :param kwargs_other: any other optional keyword arguments :return: a realization of WDM halos """ mass_definition = 'TNFW' # truncated NFW profile kwargs_model_field = { 'a_wdm': a_wdm_los, 'b_wdm': b_wdm_los, 'c_wdm': c_wdm_los, 'log_mc': log_mc, 'log_mlow': log_mlow, 'log_mhigh': log_mhigh, 'cone_opening_angle': cone_opening_angle_arcsec, 'mdef_los': mass_definition, 'mass_func_type': 'POWER_LAW', 'LOS_normalization': LOS_normalization, 'log_m_host': log_m_host, } if suppression_model_field is not None: kwargs_model_field.update( {'suppression_model': suppression_model_field}) kwargs_model_field.update( {'kwargs_suppression': kwargs_suppression_field}) kwargs_model_subhalos = { 'a_wdm': a_wdm_sub, 'b_wdm': b_wdm_sub, 'c_wdm': c_wdm_sub, 'log_mc': log_mc, 'log_mlow': log_mlow, 'log_mhigh': log_mhigh, 'cone_opening_angle': cone_opening_angle_arcsec, 'sigma_sub': sigma_sub, 'mdef_subs': mass_definition, 'mass_func_type': 'POWER_LAW', 'power_law_index': power_law_index, 'r_tidal': r_tidal } if suppression_model_sub is not None: kwargs_model_subhalos.update( {'suppression_model': suppression_model_sub}) kwargs_model_subhalos.update( {'kwargs_suppression': kwargs_suppression_sub}) kwargs_model_field.update(kwargs_other) kwargs_model_subhalos.update(kwargs_other) # this will use the default cosmology. parameters can be found in defaults.py pyhalo = pyHalo(z_lens, z_source) # Using the render method will result a list of realizations realization_subs = pyhalo.render(['SUBHALOS'], kwargs_model_subhalos, nrealizations=1)[0] realization_line_of_sight = pyhalo.render(['LINE_OF_SIGHT', 'TWO_HALO'], kwargs_model_field, nrealizations=1)[0] wdm_realization = realization_line_of_sight.join( realization_subs, join_rendering_classes=True) return wdm_realization
def run(Ntotal_cusp, Ntotal_fold, Ntotal_cross, start_idx): continue_loop = True n_computed = 0 done_cusp, done_fold, done_cross = False, False, False n_cusp, n_fold, n_cross = 0, 0, 0 if Ntotal_cusp == 0: done_cusp = True if Ntotal_fold == 0: done_fold = True if Ntotal_cross == 0: done_cross = True lens_idx = int(start_idx) + n_computed dpath = dpath_base + str(lens_idx) if os.path.exists(dpath + '/lensdata.txt'): return while continue_loop: if done_cusp and done_cross and done_fold: break while True: rein, vdis, zlens, zsrc = sample_from_strides(1) if rein <= rein_max and rein >= rein_min: if zlens <= z_lens_max: if zsrc <= z_src_max: break pyhalo = pyHalo(zlens, zsrc) print('rein, zlens, zsrc: ', str(rein) + ' ' + str(zlens) + ' ' + str(zsrc)) ellip = draw_ellip() ellip_theta = draw_ellip_PA() shear = draw_shear() shear_theta = draw_shear_PA_correlated(ellip_theta, sigma=40) halo_args = { 'mdef_main': mass_def, 'mdef_los': mass_def, 'sigma_sub': sigma_sub, 'log_mlow': log_ml, 'log_mhigh': log_mh, 'power_law_index': -1.9, 'parent_m200': M_halo, 'r_tidal': r_tidal, 'cone_opening_angle': 5 * rein, 'opening_angle_factor': 5, 'subtract_subhalo_mass_sheet': True, 'subhalo_mass_sheet_scale': 1., 'R_ein_main': rein, 'LOS_normalization': LOSnorm } realization = pyhalo.render(model_type, halo_args)[0] e1, e2 = phi_q2_ellipticity(shear_theta * np.pi / 180, 1 - ellip) gamma1, gamma2 = shear_polar2cartesian(shear_theta * np.pi / 180, shear) kwargs_lens = [{ 'theta_E': rein, 'center_x': 0, 'center_y': 0, 'e1': e1, 'e2': e2, 'gamma': gamma }, { 'gamma1': gamma1, 'gamma2': gamma2 }] macromodel = MacroLensModel([PowerLawShear(zlens, kwargs_lens)]) source_args = { 'center_x': None, 'center_y': None, 'source_fwhm_pc': source_size_fwhm_pc } quasar = Quasar(source_args) system = QuadLensSystem(macromodel, zsrc, quasar, realization, pyhalo._cosmology) print('zlens: ', zlens) print('zsrc: ', zsrc) print('src_size_pc: ', source_size_fwhm_pc) print('R_ein:', rein) print('shear, ellip: ', shear, ellip) print('nhalos: ', len(realization.halos)) continue_findimg_loop = True while continue_findimg_loop: src_r = np.random.uniform(0.01, 0.1) src_phi = np.random.uniform(-np.pi, np.pi) srcx, srcy = src_r * np.cos(src_phi), src_r * np.sin(src_phi) print(srcx, srcy, np.sqrt(srcx**2 + srcy**2)) system.update_source_centroid(srcx, srcy) lens_model_smooth, kwargs_lens_smooth = system.get_lensmodel(False) lensModel, kwargs_lens = system.get_lensmodel() x_guess, y_guess = system.solve_lens_equation( lens_model_smooth, kwargs_lens_smooth) if len(x_guess) != 4: continue min_sep = min_img_sep(x_guess, y_guess) lens_config = identify(x_guess, y_guess, rein) if min_sep < 0.2: continue if lens_config == 0: config = 'cross' if done_cross: continue elif lens_config == 1: config = 'fold' if done_fold: continue else: config = 'cusp' if done_cusp: continue print('solving lens equation with halos... ') t0 = time() #x_image, y_image = iterative_rayshooting(srcx, srcy, # x_guess, y_guess, lensModel, kwargs_lens) x_image, y_image = system.solve_lens_equation( lensModel, kwargs_lens, 10**-6) tend = time() dt = np.round(tend - t0, 2) / 60 print('solved lens equation with ' + str(len(realization.halos)) + ' halos in ' + str(dt) + ' min.') lens_config = identify(x_image, y_image, rein) min_sep = min_img_sep(x_image, y_image) if min_sep < 0.2: continue if lens_config == 0: config = 'cross' if done_cross: continue elif lens_config == 1: config = 'fold' if done_fold: continue else: config = 'cusp' if done_cusp: continue images = system.background_quasar.get_images( x_image, y_image, lensModel, kwargs_lens) break_loop = False for img in images: if flux_at_edge(img): break_loop = True if break_loop: print('flux at edge... ') continue print(config) other_lens_args = {} other_lens_args['zlens'] = zlens other_lens_args['zsrc'] = zsrc other_lens_args['gamma'] = gamma other_lens_args['config'] = config other_lens_args['source_fwhm_pc'] = source_size_fwhm_pc other_lens_args['rmax2d_asec'] = 3 * rein continue_findimg_loop = False if lens_config == 0: n_cross += 1 if n_cross == Ntotal_cross: done_cross = True elif lens_config == 1: n_fold += 1 if n_fold == Ntotal_fold: done_fold = True else: n_cusp += 1 if n_cusp == Ntotal_cusp: done_cusp = True n_computed += 1 create_directory(dpath) x_image += np.random.normal(0, 0.005, 4) y_image += np.random.normal(0, 0.005, 4) magnifications = system.quasar_magnification(x_image, y_image, lensModel, kwargs_lens) data_with_halos = LensedQuasar(x_image, y_image, magnifications) data_with_halos.nimg = 4 data_with_halos.srcx = 0. data_with_halos.srcy = 0. data_with_halos.t = [0., 0., 0., 0.] write_data(dpath + '/lensdata.txt', [data_with_halos], mode='write') to_write = get_info_string(halo_args, other_lens_args) write_info(str(to_write), dpath + '/info.txt')
def setup(self): self.pyhalo = pyHalo(0.5, 2.)
def run_lenstronomy(data, prior, keys, keys_to_vary, output_path, write_header, readout_best): chaindata = [] parameters = [] start = True N_computed = 0 t0 = time.time() if 'readout_steps' in keys.keys(): readout_steps = keys['readout_steps'] else: readout_steps = 50 if 'n_particles' in keys.keys(): n_particles = keys['n_particles'] else: n_particles = 20 if 'simplex_n_iter' in keys.keys(): simplex_n_iter = keys['simplex_n_iter'] else: simplex_n_iter = 200 if 'n_iterations' in keys.keys(): n_iterations = keys['n_iterations'] else: n_iterations = 250 if 'verbose' in keys.keys(): verbose = keys['verbose'] else: verbose = False if verbose: print('Running with:') print('n_particles: ', n_particles) print('n_iterations: ', n_iterations) print('simplex_iterations: ', simplex_n_iter) current_best = 1e+6 best_fluxes = [0,0,0,0] if write_header: save_statistic = True else: save_statistic = False if 'lens_redshift' not in keys_to_vary.keys(): halo_constructor = pyHalo(np.round(keys['zlens'], 2), np.round(keys['zsrc'], 2)) while N_computed < keys['Nsamples']: d2fit = perturb_data(data, keys['position_sigma'], keys['flux_sigma']) print('N computed: ', N_computed) while True: samples = prior.sample(scale_by='Nsamples')[0] chain_keys_run = copy(keys) for i,pname in enumerate(keys_to_vary.keys()): chain_keys_run[pname] = samples[i] if 'lens_redshift' in keys_to_vary.keys(): halo_constructor = pyHalo(np.round(chain_keys_run['lens_redshift'], 2), np.round(chain_keys_run['zsrc'], 2)) if 'shear' in keys_to_vary.keys(): opt_routine = 'fixedshearpowerlaw' constrain_params = {'shear': chain_keys_run['shear']} else: opt_routine = 'fixed_powerlaw_shear' constrain_params = None kwargs_init = [{'theta_E': 1., 'center_x': 0., 'center_y': 0, 'e1': 0.1, 'e2': 0.1, 'gamma': chain_keys_run['SIE_gamma']}, {'gamma1': 0.02, 'gamma2': 0.01}] lens_main = PowerLawShear(halo_constructor.zlens, kwargs_init) lens_list = [lens_main] kwargs_realization = halo_model_args(chain_keys_run, verbose) include_satellites = update_satellites(chain_keys_run, keys_to_vary) if include_satellites is not None: kwargs, zsat, nsat = include_satellites[0], include_satellites[1] assert nsat < 3 if nsat < 2: if 'lens_redshift' in keys_to_vary.keys(): raise Exception('must allow for satellite redshift to vary with lens redshift') satellite = SISsatellite(zsat[0], kwargs[0]) lens_list.append(satellite) if nsat < 3: satellite = SISsatellite(zsat[1], kwargs[1]) lens_list.append(satellite) macromodel = MacroLensModel(lens_list) out = forward_model(d2fit.x, d2fit.y, d2fit.m, macromodel, chain_keys_run['source_fwhm_pc'], halo_constructor, kwargs_realization, chain_keys_run['mass_func_type'], opt_routine, constrain_params, verbose, test_mode=False) blended = out['blended'] if blended: print('images blended together') continue if np.isfinite(out['summary_stat']): break N_computed += 1 if N_computed%readout_steps == 0 and verbose: print('completed ' + str(N_computed) + ' of '+str(keys['Nsamples'])+'...') samples_array = [] for pname in keys_to_vary.keys(): samples_array.append(chain_keys_run[pname]) if 'shear' not in keys_to_vary.keys() and 'save_shear' in keys.keys(): samples_array.insert(keys['save_shear']['idx'], np.round(out['external_shear'],4)) if save_statistic: new_statistic = out['summary_stat'] #print(new_statistic, current_best) if new_statistic < current_best: current_best = new_statistic params_best = samples_array best_fluxes = out['magnifications_fit'] if start: macro_array = out['macromodel_parameters'] chaindata = out['magnifications_fit'] parameters = np.array(samples_array) else: macro_array = np.vstack((macro_array, out['macromodel_parameters'])) chaindata = np.vstack((chaindata, out['magnifications_fit'])) parameters = np.vstack((parameters, np.array(samples_array))) if N_computed%readout_steps == 0: readout_macro(output_path, macro_array, write_header) readout(output_path, chaindata, parameters, list(keys_to_vary.keys()), write_header) if save_statistic and readout_best: readout_realizations(out['lens_system_optimized'], output_path, current_best, params_best, best_fluxes) start = True write_header = False else: start = False if verbose: print('time elapsed: ', time.time() - t0) return chaindata, parameters
def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13 LOS_normalization = 1. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.1 delta_power_law_index_coupling = 0.5 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.1 power_law_index = -1.9 subhalo_spatial_distribution = 'HOST_NFW' kwargs_cdm = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'mdef_los': 'TNFW', 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs' } pyhalo = pyHalo(zlens, zsource) self.realization_cdm = pyhalo.render(['TWO_HALO'], kwargs_cdm)[0] lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts( kwargs_cdm) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, zlens, zsource, kwargs_cdm['log_mlow'], kwargs_cdm['log_mhigh'], kwargs_cdm['cone_opening_angle'], m_pivot=kwargs_cdm['m_pivot'], geometry_type='DOUBLE_CONE') self.geometry = Geometry(cosmo, zlens, zsource, kwargs_cdm['cone_opening_angle'], 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm self.rendering_class = TwoHaloContribution( kwargs_cdm, self.halo_mass_function, self.geometry, self.lens_cosmo, self.lens_plane_redshifts, self.delta_zs)
def setup(self): zlens, zsource = 0.5, 2. zmin = 0.01 zmax = 1.98 log_mlow = 6. log_mhigh = 9. host_m200 = 10**13 LOS_normalization = 100. draw_poisson = False log_mass_sheet_min = 7. log_mass_sheet_max = 10. kappa_scale = 1. delta_power_law_index = -0.17 delta_power_law_index_coupling = 0.7 cone_opening_angle = 6. m_pivot = 10**8 sigma_sub = 0.6 power_law_index = -1.8 subhalo_spatial_distribution = 'HOST_NFW' kwargs_cdm = { 'zmin': zmin, 'zmax': zmax, 'log_mc': None, 'log_mlow': log_mlow, 'sigma_sub': sigma_sub, 'c_scale': None, 'c_power': None, 'a_wdm': None, 'b_wdm': None, 'c_wdm': None, 'c_scatter_dex': 0.2, 'log_mhigh': log_mhigh, 'host_m200': host_m200, 'LOS_normalization': LOS_normalization, 'draw_poisson': draw_poisson, 'subhalo_spatial_distribution': subhalo_spatial_distribution, 'log_mass_sheet_min': log_mass_sheet_min, 'log_mass_sheet_max': log_mass_sheet_max, 'kappa_scale': kappa_scale, 'power_law_index': power_law_index, 'delta_power_law_index': delta_power_law_index, 'delta_power_law_index_coupling': delta_power_law_index_coupling, 'm_pivot': m_pivot, 'cone_opening_angle': cone_opening_angle, 'subhalo_mass_sheet_scale': 1., 'subhalo_convergence_correction_profile': 'NFW', 'r_tidal': '0.5Rs', 'mdef_subs': 'TNFW', 'mdef_los': 'TNFW' } kwargs_wdm = deepcopy(kwargs_cdm) log_mc = 7.1 a_wdm = 1. b_wdm = 0.8 c_wdm = -1.3 kwargs_wdm['log_mc'] = log_mc kwargs_wdm['a_wdm'] = a_wdm kwargs_wdm['b_wdm'] = b_wdm kwargs_wdm['c_wdm'] = c_wdm kwargs_wdm['c_scale'] = 60. kwargs_wdm['c_power'] = -0.17 pyhalo = pyHalo(zlens, zsource) lens_plane_redshifts, delta_zs = pyhalo.lens_plane_redshifts( kwargs_cdm) cosmo = Cosmology() self.lens_plane_redshifts = lens_plane_redshifts self.delta_zs = delta_zs self.halo_mass_function = LensingMassFunction( cosmo, zlens, zsource, kwargs_cdm['log_mlow'], kwargs_cdm['log_mhigh'], kwargs_cdm['cone_opening_angle'], m_pivot=kwargs_cdm['m_pivot'], geometry_type='DOUBLE_CONE', use_lookup_table=True) self.geometry = Geometry(cosmo, zlens, zsource, kwargs_cdm['cone_opening_angle'], 'DOUBLE_CONE') self.lens_cosmo = LensCosmo(zlens, zsource, cosmo) self.kwargs_cdm = kwargs_cdm self.kwargs_wdm = kwargs_wdm pyhalo = pyHalo(zlens, zsource) model_list_field = ['LINE_OF_SIGHT'] model_list_sub = ['SUBHALOS'] self.realization_cdm = pyhalo.render(model_list_sub + model_list_field, kwargs_cdm)[0] self.realization_cdm_field = pyhalo.render(model_list_field, kwargs_cdm)[0] self.realization_wdm_field = pyhalo.render(model_list_field, kwargs_wdm)[0] self.realization_wdm_subhalos = pyhalo.render(model_list_sub, kwargs_wdm)[0]
def run( Ntotal_cusp, Ntotal_fold, Ntotal_cross, start_idx, ): continue_loop = True n_computed = 0 done_cusp, done_fold, done_cross = False, False, False n_cusp, n_fold, n_cross = 0, 0, 0 if Ntotal_cusp == 0: done_cusp = True if Ntotal_fold == 0: done_fold = True if Ntotal_cross == 0: done_cross = True lens_idx = int(start_idx) + n_computed dpath = dpath_base + str(lens_idx) l = LensCosmo(0.5, 4) if os.path.exists(dpath + '/lensdata.txt'): return while continue_loop: if done_cusp and done_cross and done_fold: break rein, vdis, zlens, zsrc = sample_from_strides(1) sigma = l.sigmasub_from_fsub(0.045, zlens, zsrc) if sigma < 1.8: continue if sigma > 2.2: continue print('vdis, rein, zlens, zsrc: ', str(vdis) + ' ' + str(rein) + ' ' + str(zlens) + ' ' + str(zsrc)) ellip = draw_ellip() ellip_theta = draw_ellip_PA() shear = draw_shear() #shear_theta = draw_shear_PA() shear_theta = draw_shear_PA_correlated(ellip_theta, sigma=50) gamma = np.round(np.random.normal(2.08, 0.05), 2) while True: source_size_kpc = np.round( np.random.normal(src_size_mean, src_size_sigma), 3) if source_size_kpc < 0.01: continue if source_size_kpc > 0.06: continue else: break pyhalo = pyHalo(zlens, zsrc) c = LensCosmo(zlens, zsrc) solver = SolveRoutines(zlens, zsrc) analysis = Analysis(zlens, zsrc) #rein = c.vdis_to_Rein(zlens, zsrc, vdis) halo_args = { 'mdef_main': 'TNFW', 'mdef_los': 'TNFW', 'fsub': fsub, 'log_mlow': log_ml, 'log_mhigh': log_mh, 'power_law_index': -1.9, 'log_m_break': logmhm, 'parent_m200': M_halo, 'parent_c': 4, 'mdef': 'TNFW', 'break_index': -1.3, 'c_scale': 60, 'c_power': -0.17, 'r_tidal': r_core, 'break_index': break_index, 'c_scale': 60, 'cone_opening_angle': 6 * rein } real = pyhalo.render(model_type, halo_args) lens_args = { 'R_ein': c.vdis_to_Rein(zlens, zsrc, vdis), 'x': 0, 'y': 0, 'ellip': ellip, 'ellip_theta': ellip_theta, 'gamma': gamma, 'shear': shear, 'shear_theta': shear_theta } start = Deflector(subclass=SIE(), redshift=zlens, **lens_args) print('zlens: ', zlens) print('zsrc: ', zsrc) print('src_size_kpc: ', source_size_kpc) print('vdis:', vdis) print('R_ein:', rein) print('shear, ellip: ', shear, ellip) print('nhalos: ', len(real[0].x)) xcaus, ycaus = None, None continue_findimg_loop = True while continue_findimg_loop: if xcaus is not None: xs_init, ys_init = guess_source(xcaus, ycaus) else: xs_init, ys_init = np.random.uniform(-0.1, 0.1), np.random.uniform( -0.1, 0.1) data_withhalos, xcaus, ycaus = imgFinder(start, real, xs_init, ys_init, True, solver, analysis) lens_config = identify(data_withhalos[0].x, data_withhalos[0].y, c.vdis_to_Rein(zlens, zsrc, vdis)) min_sep = min_img_sep(data_withhalos[0].x, data_withhalos[0].y) #print('minimum image separation: ', min_sep) if min_sep < rein * 0.2: continue if lens_config == 0: config = 'cross' if done_cross: continue elif lens_config == 1: config = 'fold' if done_fold: continue else: config = 'cusp' if done_cusp: continue print(config) other_lens_args = {} other_lens_args['zlens'] = zlens other_lens_args['zsrc'] = zsrc other_lens_args['gamma'] = gamma other_lens_args['config'] = config other_lens_args['source_size_kpc'] = source_size_kpc other_lens_args['rmax2d_asec'] = 3 * rein continue_findimg_loop = False save = True for i in range(0, 4): magnifications, image = analysis.raytrace_images( macromodel=start, xcoord=data_withhalos[0].x[i], ycoord=data_withhalos[0].y[i], realizations=real, multiplane=multiplane, srcx=data_withhalos[0].srcx, srcy=data_withhalos[0].srcy, res=0.01, method='lenstronomy', source_shape='GAUSSIAN', source_size_kpc=source_size_kpc) if flux_at_edge(image): print('images are blended... continuing loop.') save = False break if save is False: continue else: if lens_config == 0: n_cross += 1 if n_cross == Ntotal_cross: done_cross = True elif lens_config == 1: n_fold += 1 if n_fold == Ntotal_fold: done_fold = True else: n_cusp += 1 if n_cusp == Ntotal_cusp: done_cusp = True n_computed += 1 create_directory(dpath) data_withhalos[0].x += np.random.normal(0, 0.003, 4) data_withhalos[0].y += np.random.normal(0, 0.003, 4) write_data(dpath + '/lensdata.txt', data_withhalos, mode='write') system = solver.build_system(main=start, realization=real[0], multiplane=True) zlist, lens_list, arg_list = system.lenstronomy_lists() with open(dpath + '/redshifts.txt', 'w') as f: np.savetxt(f, X=zlist) with open(dpath + '/lens_list.txt', 'w') as f: f.write(str(lens_list)) with open(dpath + '/lens_args.txt', 'w') as f: f.write(str(arg_list)) to_write = get_info_string(halo_args, other_lens_args) write_info(str(to_write), dpath + '/info.txt')
def compute_fluxratio_distributions(halo_model='', model_args={}, data2fit=None, Ntotal=int, outfilename='', zlens=None, zsrc=None, start_macromodel=None, identifier=None, satellites=None, source_size_kpc=None, write_to_file=False, outfilepath=None, n_restart=1, pso_conv_mean = 100, source_x = 0, source_y = 0, grid_res = 0.002, LOS_mass_sheet_front = 7.7, LOS_mass_sheet_back = 8, multiplane=True, **kwargs): tstart = time() data = Data(x=data2fit[0],y=data2fit[1],m=data2fit[2],t=data2fit[3],source=[source_x, source_y]) if write_to_file: assert outfilepath is not None assert os.path.exists(outfilepath) if start_macromodel is None: start_macromodel = get_default_SIE(zlens) start_macromodel.redshift = zlens if start_macromodel is None: start_macromodel = get_default_SIE(zlens) start_macromodel.redshift = zlens solver = SolveRoutines(zlens=zlens, zsrc=zsrc, temp_folder=identifier) # initialize macromodel fit_fluxes = [] shears, shear_pa, xcen, ycen = [], [], [], [] pyhalo = pyHalo(zlens,zsrc) while len(fit_fluxes)<Ntotal: #print(str(len(fit_fluxes)) +' of '+str(Ntotal)) print('rendering... ') realization = pyhalo.render(halo_model,model_args)[0] print('done.') realization = realization.shift_background_to_source(source_x, source_y) model_data, system, outputs, _ = solver.hierarchical_optimization(datatofit=data, macromodel=start_macromodel, realization=realization, multiplane=multiplane, n_particles=20, simplex_n_iter=400, n_iterations=300, source_size_kpc=source_size_kpc, optimize_routine='fixed_powerlaw_shear', verbose=True, pso_convergence_mean=pso_conv_mean, re_optimize=False, particle_swarm=True, tol_mag=None, pso_compute_magnification=700, restart=n_restart, grid_res=grid_res, LOS_mass_sheet_front = LOS_mass_sheet_front, LOS_mass_sheet_back = LOS_mass_sheet_back, satellites=satellites, **kwargs) for sys,dset in zip(system,model_data): if dset.nimg != data.nimg: continue astro_error = chi_square_img(data.x,data.y,dset.x,dset.y,0.003,reorder=False) if astro_error > 1: continue fit_fluxes.append(dset.flux_anomaly(data, sum_in_quad=False, index=0)) write_fluxes(fluxratio_data_path+identifier + 'fluxes_'+outfilename+'.txt', fit_fluxes, summed_in_quad=False) tend = time() runtime = (tend - tstart)*60**-1 with open(fluxratio_data_path+identifier +'runtime_'+outfilename+'.txt', 'a') as f: f.write(str(np.round(runtime, 2))+'\n')