Example #1
0
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)
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
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)

    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')
Example #6
0
    def setup(self):

        self.pyhalo = pyHalo(0.5, 2.)
Example #7
0
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
Example #8
0
    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)
Example #9
0
    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]
Example #10
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')