Beispiel #1
0
    def temporal_smearing(self, lobs, zsource, cosmo=None):
        """ Temporal smearing due to turbulent scattering

        Parameters
        ----------
        lobs : Quantity
          Observed wavelength
        zsource : float
        cosmo : astropy.cosmology, optional

        Returns
        -------
        tau : Quantity
          temporal broadening
        """
        # Cosmology
        if cosmo is None:
            from astropy.cosmology import Planck15 as cosmo
        D_S = cosmo.angular_diameter_distance(zsource)
        D_L = cosmo.angular_diameter_distance(self.zL)
        D_LS = cosmo.angular_diameter_distance_z1z2(self.zL, zsource)
        # Angular
        theta = self.angular_broadening(lobs, zsource, cosmo=cosmo)
        # Calculate
        tau = D_L * D_S * (theta.to('radian').value)**2 / D_LS / const.c / (
            1 + self.zL)
        # Return
        return tau.to('ms')
Beispiel #2
0
def cal_einstein_radius_in_arcsec(z_l,z_s,sigma):
    #b_sie = 4*pi * sigma^2/c^2 * D_ls/D_s
    c = const.c.value / 1000 #to km/s 
    v_fac = (sigma/c)**2
    d_fac = cosmo.angular_diameter_distance_z1z2(z_l, z_s).value/cosmo.angular_diameter_distance(z_s).value
    radian_to_arcsec = 180.0/np.pi*60*60
    return 4.0*np.pi*v_fac*d_fac*radian_to_arcsec
def update(val):
      zL,zS = slzL.val,slzS.val
      xL,yL = slxL.val, slyL.val
      ML,eL,PAL = slML.val,sleL.val,slPAL.val
      sh,sha = slss.val,slsa.val
      xs,ys = slxs.val, slys.val
      Fs,ws = slFs.val, slws.val
      ns,ars,pas = slns.val,slars.val,slPAs.val
      newDd = cosmo.angular_diameter_distance(zL).value
      newDs = cosmo.angular_diameter_distance(zS).value
      newDds= cosmo.angular_diameter_distance_z1z2(zL,zS).value
      newLens = vl.SIELens(zLens,xL,yL,10**ML,eL,PAL)
      newShear = vl.ExternalShear(sh,sha)
      newSource = vl.SersicSource(zS,True,xs,ys,Fs,ws,ns,ars,pas)
      xs,ys = vl.LensRayTrace(xim,yim,[newLens,newShear],newDd,newDs,newDds)
      imbg = vl.SourceProfile(xim,yim,newSource,[newLens,newShear])
      imlensed = vl.SourceProfile(xs,ys,newSource,[newLens,newShear])
      caustics = vl.CausticsSIE(newLens,newDd,newDs,newDds,newShear)

      ax.cla()

      ax.imshow(imbg,cmap=cmbg,extent=[xim.min(),xim.max(),yim.min(),yim.max()],origin='lower')
      ax.imshow(imlensed,cmap=cmlens,extent=[xim.min(),xim.max(),yim.min(),yim.max()],origin='lower')
      mu = imlensed.sum()*(xim[0,1]-xim[0,0])**2 / newSource.flux['value']
      ax.text(0.9,1.02,'$\\mu$ = {0:.2f}'.format(mu),transform=ax.transAxes)

      #for i in range(caustics.shape[0]):
      #      ax.plot(caustics[i,0,:],caustics[i,1,:],'k-')
      for caustic in caustics:
      		ax.plot(caustic[:,0],caustic[:,1],'k-')

      f.canvas.draw_idle()
Beispiel #4
0
def create_modelimage(lens,source,xmap,ymap,xemit,yemit,indices,
      Dd=None,Ds=None,Dds=None,sourcedatamap=None):
      """
      Creates a model lensed image given the objects and map
      coordinates specified.  Supposed to be common for both
      image fitting and visibility fitting, so we don't need
      any data here.

      Returns:
      immap
            A 2D array representing the field evaluated at
            xmap,ymap with all sources included.
      mus:
            A numpy array of length N_sources containing the
            magnifications of each source (1 if unlensed).
      """
      
      lens = list(np.array([lens]).flatten()) # Ensure lens(es) are a list
      source = list(np.array([source]).flatten()) # Ensure source(s) are a list
      mus = np.zeros(len(source))
      immap, imsrc = np.zeros(xmap.shape), np.zeros(xemit.shape)

      # If we didn't get pre-calculated distances, figure them here assuming Planck15
      if np.any((Dd is None,Ds is None, Dds is None)):
            from astropy.cosmology import Planck15 as cosmo
            Dd = cosmo.angular_diameter_distance(lens[0].z).value
            Ds = cosmo.angular_diameter_distance(source[0].z).value
            Dds= cosmo.angular_diameter_distance_z1z2(lens[0].z,source[0].z).value

      # Do the raytracing for this set of lens & shear params
      xsrc,ysrc = LensRayTrace(xemit,yemit,lens,Dd,Ds,Dds)

      if sourcedatamap is not None: # ... then particular source(s) are specified for this map
            for jsrc in sourcedatamap:
                  if source[jsrc].lensed: 
                        ims = SourceProfile(xsrc,ysrc,source[jsrc],lens)
                        imsrc += ims
                        mus[jsrc] = ims.sum()*(xemit[0,1]-xemit[0,0])**2./source[jsrc].flux['value']
                  else: immap += SourceProfile(xmap,ymap,source[jsrc],lens); mus[jsrc] = 1.
      else: # Assume we put all sources in this map/field
            for j,src in enumerate(source):
                  if src.lensed: 
                        ims = SourceProfile(xsrc,ysrc,src,lens)
                        imsrc += ims
                        mus[j] = ims.sum()*(xemit[0,1]-xemit[0,0])**2./src.flux['value']
                  else: immap += SourceProfile(xmap,ymap,src,lens); mus[j] = 1.

      # Try to reproduce matlab's antialiasing thing; this uses a 3lobe lanczos low-pass filter
      imsrc = Image.fromarray(imsrc)
      resize = np.array(imsrc.resize((int(indices[1]-indices[0]),int(indices[3]-indices[2])),Image.ANTIALIAS))
      immap[indices[2]:indices[3],indices[0]:indices[1]] += resize

      # Flip image to match sky coords (so coordinate convention is +y = N, +x = W, angle is deg E of N)
      immap = immap[::-1,:]

      # last, correct for pixel size.
      immap *= (xmap[0,1]-xmap[0,0])**2.

      return immap,mus
def update(val):
    zL, zS = slzL.val, slzS.val
    xL, yL = slxL.val, slyL.val
    ML, eL, PAL = slML.val, sleL.val, slPAL.val
    sh, sha = slss.val, slsa.val
    xs, ys = slxs.val, slys.val
    Fs, ws = slFs.val, slws.val
    ns, ars, pas = slns.val, slars.val, slPAs.val
    newDd = cosmo.angular_diameter_distance(zL).value
    newDs = cosmo.angular_diameter_distance(zS).value
    newDds = cosmo.angular_diameter_distance_z1z2(zL, zS).value
    newLens = vl.SIELens(zLens, xL, yL, 10**ML, eL, PAL)
    newShear = vl.ExternalShear(sh, sha)
    newSource = vl.SersicSource(zS, True, xs, ys, Fs, ws, ns, ars, pas)
    xs, ys = vl.LensRayTrace(xim, yim, [newLens, newShear], newDd, newDs,
                             newDds)
    imbg = vl.SourceProfile(xim, yim, newSource, [newLens, newShear])
    imlensed = vl.SourceProfile(xs, ys, newSource, [newLens, newShear])
    caustics = vl.CausticsSIE(newLens, newDd, newDs, newDds, newShear)

    ax.cla()

    ax.imshow(imbg,
              cmap=cmbg,
              extent=[xim.min(), xim.max(),
                      yim.min(), yim.max()],
              origin='lower')
    ax.imshow(imlensed,
              cmap=cmlens,
              extent=[xim.min(), xim.max(),
                      yim.min(), yim.max()],
              origin='lower')
    mu = imlensed.sum() * (xim[0, 1] - xim[0, 0])**2 / newSource.flux['value']
    ax.text(0.9, 1.02, '$\\mu$ = {0:.2f}'.format(mu), transform=ax.transAxes)

    #for i in range(caustics.shape[0]):
    #      ax.plot(caustics[i,0,:],caustics[i,1,:],'k-')
    for caustic in caustics:
        ax.plot(caustic[:, 0], caustic[:, 1], 'k-')

    f.canvas.draw_idle()
Beispiel #6
0
def update(val):
      zL,zS = slzL.val,slzS.val
      xL,yL = slxL.val, slyL.val
      ML,eL,PAL = slML.val,sleL.val,slPAL.val
      sh,sha = slss.val,slsa.val
      newDd = cosmo.angular_diameter_distance(zL).value
      newDs = cosmo.angular_diameter_distance(zS).value
      newDds= cosmo.angular_diameter_distance_z1z2(zL,zS).value
      newLens = vl.SIELens(zLens,xL,yL,10**ML,eL,PAL)
      newShear = vl.ExternalShear(sh,sha)
      xsource,ysource = vl.LensRayTrace(xim,yim,[newLens,newShear],newDd,newDs,newDds)
      caustics = vl.get_caustics([newLens,newShear],newDd,newDs,newDds)
      ax.cla()
      ax.plot(xsource,ysource,'b-')
      for caustic in caustics:
            ax.plot(caustic[:,0],caustic[:,1],'k-')
      #ax.set_xlim(-0.5,0.5)
      #ax.set_ylim(-0.5,0.5)
      #for i in range(len(xs)):
      #      p[i].set_xdata(xs[i])
      #      p[i].set_ydata(ys[i])
      f.canvas.draw_idle()
Beispiel #7
0
    def angular_broadening(self, lobs, zsource, cosmo=None):
        """ Broadening of a point source due to turbulent scattering

        Parameters
        ----------
        lobs : Quantity
          Observed wavelength
        zsource : float
          Redshift of radio source

        Returns
        -------
        theta : Quantity
          Angular broadening.  Radius (half-width at half-max)
        """
        if self.regime == 0:
            raise ValueError("Need to set rdiff and the regime first!")
        if cosmo is None:
            from astropy.cosmology import Planck15 as cosmo
        # f
        if (self.regime == 1) or np.isclose(self.beta, 4.):
            f = 1.18
        elif (self.regime == 2) and np.isclose(self.beta, 11 / 3.):
            f = 1.01
        # Distances
        D_S = cosmo.angular_diameter_distance(zsource)
        D_LS = cosmo.angular_diameter_distance_z1z2(self.zL, zsource)
        if self.verbose:
            print("D_LS={}, D_S={}".format(D_LS, D_S))
        D_LS_D_S = D_LS / D_S

        # Evaluate
        k = 2 * np.pi / (lobs / (1 + self.zL)
                         )  # Are we sure about this (1+z) factor?!
        self.theta = f * D_LS_D_S / (k * self.rdiff) * u.radian

        return self.theta.to('arcsec')
xim, yim = np.meshgrid(xim, yim)

zLens, zSource = 0.8, 5.656
xLens, yLens = 0., 0.
MLens, eLens, PALens = 2.87e11, 0.5, 70.
xSource, ySource, FSource = 0.216, 0.24, 0.02  # arcsec, arcsec, Jy
aSource, nSource, arSource, PAsource = 0.1, 0.5, 1.0, 120. - 90  # arcsec,[],[],deg CCW from x-axis
shear, shearangle = 0.12, 120.

Lens = vl.SIELens(zLens, xLens, yLens, MLens, eLens, PALens)
Shear = vl.ExternalShear(shear, shearangle)
Source = vl.SersicSource(zSource, True, xSource, ySource, FSource, aSource,
                         nSource, arSource, PAsource)
Dd = cosmo.angular_diameter_distance(zLens).value
Ds = cosmo.angular_diameter_distance(zSource).value
Dds = cosmo.angular_diameter_distance_z1z2(zLens, zSource).value

xsource, ysource = vl.LensRayTrace(xim, yim, [Lens, Shear], Dd, Ds, Dds)

imbg = vl.SourceProfile(xim, yim, Source, [Lens, Shear])
imlensed = vl.SourceProfile(xsource, ysource, Source, [Lens, Shear])
caustics = vl.CausticsSIE(Lens, Dd, Ds, Dds, Shear)

f = pl.figure(figsize=(12, 6))
ax = f.add_subplot(111, aspect='equal')
pl.subplots_adjust(right=0.48, top=0.97, bottom=0.03, left=0.05)

cmbg = cm.cool
cmbg._init()
cmbg._lut[0, -1] = 0.
def lens_efficiency(z_lens, z_src):
    """Calculates the efficiency of the lensing system given source and lens redshifts."""
    dist_lens_source = cosmo.angular_diameter_distance_z1z2(z_lens,
                                                            z_src).value
    dist_observer_source = cosmo.angular_diameter_distance(z_src).value
    return dist_lens_source / dist_observer_source
Beispiel #10
0
    def __init__(
        self,
        mag_zero=25.5,
        mag_iso=22.5,
        exposure=1610.0,
        fwhm_psf=0.18,
        pixel_size=0.1,
        n_xy=64,
        f_sub=0.05,
        beta=-1.9,
        m_min_calib=1e6 * M_s,
        m_max_sub_div_M_hst_calib=0.01,
        m_200_min_sub=1e7 * M_s,
        m_200_max_sub_div_M_hst=0.01,
        M_200_sigma_v_scatter=False,
        params_eval=None,
        calculate_joint_score=False,
        calculate_msub_derivatives=False,
        calculate_sub_residuals=False,
        draw_host_mass=True,
        draw_host_redshift=True,
        draw_alignment=True,
        roi_size=2.,
    ):
        """
        Class to simulation an observation strong lensing image, with substructure sprinkled in.

        :param mag_zero: Zero-point magnitude of observation
        :param mag_iso: Magnitude of isotropic sky brightness
        :param exposure: Exposure time of observation, in seconds (including gain)
        :param fwhm_psf: FWHM of Gaussian PSF, in arcsecs
        :param pixel_size: Pixel side size, in arcsecs
        :param n_xy: Number of pixels (along x and y) of observation

        :param f_sub: Fraction of total contained mass in substructure
        :param beta: Slope in the subhaalo mass function
        :param m_min_calib: Minimum mass above which subhalo mass fraction is `f_sub`
        :param m_max_sub_div_M_hst_calib: Maximum mass below which subhalo mass fraction is `f_sub`,
            in units of the host halo mass
        :param m_200_min_sub: Lowest mass of subhalos to draw
        :param m_200_max_sub_div_M_hst: Maximum mass of subhalos to draw, in units of host halo mass

        :param M_200_sigma_v_scatter: Whether to apply lognormal scatter in sigma_v to M_200_host mapping

        :param params_eval: Parameters (f_sub, beta) for which p(x,z|params) will be calculated
        :param calculate_joint_score: Whether grad_params log p(x,z|params) will be calculated
        :param calculate_msub_derivatives: Whether to calculate derivatives of image wrt subhalos masses
        :param calculate_residuals: Whether to calculate residual images wrt subhalos
        """

        # beta = -2.0 is forbidden!
        if np.abs((beta + 2.)) < 1.e-3:
            beta = -2.001

        # Store input
        self.mag_zero = mag_zero
        self.mag_iso = mag_iso
        self.exposure = exposure
        self.fwhm_psf = fwhm_psf
        self.pixel_size = pixel_size
        self.n_xy = n_xy
        self.f_sub = f_sub
        self.beta = beta
        self.m_min_calib = m_min_calib
        self.m_max_sub_div_M_hst_calib = m_max_sub_div_M_hst_calib
        self.m_200_min_sub = m_200_min_sub
        self.m_200_max_sub_div_M_hst = m_200_max_sub_div_M_hst
        self.M_200_sigma_v_scatter = M_200_sigma_v_scatter
        self.params_eval = params_eval
        self.calculate_joint_score = calculate_joint_score
        self.draw_host_mass = draw_host_mass
        self.draw_host_redshift = draw_host_redshift
        self.draw_alignment = draw_alignment

        self.coordinate_limit = pixel_size * n_xy / 2.0

        # Draw lens properties consistent with Collett et al [1507.02657]

        # Clip lens redshift `z_l` to be less than 1; high-redshift lenses no good for our purposes!

        if self.draw_host_redshift:
            self.z_l = 2.0
            while self.z_l > 1.0:
                self.z_l = 10 ** np.random.normal(-0.25, 0.25)
        else:
            self.z_l = 10.0 ** -0.25

        if self.draw_host_mass:
            self.sigma_v = np.random.normal(225, 50)
        else:
            self.sigma_v = 225.0

        if self.draw_alignment:
            self.theta_x_0 = np.random.normal(0, 0.2)
            self.theta_y_0 = np.random.normal(0, 0.2)
        else:
            self.theta_x_0 = 0.0
            self.theta_y_0 = 0.0

        q = 1  # For now, hard-code host to be spherical

        # Fix the source properties to reasonable mean-ish values
        self.theta_s_e = 0.2
        self.z_s = 1.5
        self.mag_s = 23.0

        # Get relevant distances
        self.D_l = Planck15.angular_diameter_distance(z=self.z_l).value * Mpc
        D_s = Planck15.angular_diameter_distance(z=self.z_s).value * Mpc
        D_ls = Planck15.angular_diameter_distance_z1z2(z1=self.z_l, z2=self.z_s).value * Mpc

        # Get properties for NFW host DM halo
        if draw_host_mass:
            self.M_200_hst = self.M_200_sigma_v(self.sigma_v * Kmps, scatter=M_200_sigma_v_scatter)
        else:
            self.M_200_hst = self.M_200_sigma_v(self.sigma_v * Kmps, scatter=0.0)

        c_200_hst = MassProfileNFW.c_200_SCP(self.M_200_hst)
        r_s_hst, rho_s_hst = MassProfileNFW.get_r_s_rho_s_NFW(self.M_200_hst, c_200_hst)

        # Get properties for SIE host
        self.theta_E = MassProfileSIE.theta_E(self.sigma_v * Kmps, D_ls, D_s)

        # Don't consider configuration with subhalo fraction > 1!
        self.f_sub_realiz = 2.0
        while self.f_sub_realiz > 1.0:

            # Generate a subhalo population...
            ps = SubhaloPopulation(
                f_sub=f_sub,
                beta=beta,
                M_hst=self.M_200_hst,
                c_hst=c_200_hst,
                m_min=m_200_min_sub,
                m_max=m_200_max_sub_div_M_hst * self.M_200_hst,
                m_min_calib=m_min_calib,
                m_max_calib=m_max_sub_div_M_hst_calib * self.M_200_hst,
                theta_s=r_s_hst / self.D_l,
                theta_roi=roi_size * self.theta_E,
                theta_E=self.theta_E,
                params_eval=params_eval,
                calculate_joint_score=calculate_joint_score,
            )

            # ... and grab its properties
            self.m_subs = ps.m_sample
            self.n_sub_roi = ps.n_sub_roi
            self.theta_xs = ps.theta_x_sample
            self.theta_ys = ps.theta_y_sample
            self.f_sub_realiz = ps.f_sub_realiz
            self.n_sub_in_ring = ps.n_sub_in_ring
            self.f_sub_in_ring = ps.f_sub_in_ring
            self.n_sub_near_ring = ps.n_sub_near_ring
            self.f_sub_near_ring = ps.f_sub_near_ring

        # Convert magnitude for source and isotropic component to expected counts
        self.S_tot = self._mag_to_flux(self.mag_s, self.mag_zero)
        self.f_iso = self._mag_to_flux(self.mag_iso, self.mag_zero)

        # Set host properties. Host assumed to be at the center of the image.
        self.hst_param_dict = {"profile": "SIE", "theta_x_0": 0.0, "theta_y_0": 0.0, "theta_E": self.theta_E, "q": q}

        lens_list = [self.hst_param_dict]

        # Set subhalo properties

        for i_sub, (m, theta_x, theta_y) in enumerate(zip(self.m_subs, self.theta_xs, self.theta_ys)):
            c = MassProfileNFW.c_200_SCP(m)
            r_s, rho_s = MassProfileNFW.get_r_s_rho_s_NFW(m, c)
            sub_param_dict = {"profile": "NFW", "theta_x_0": theta_x, "theta_y_0": theta_y, "M_200": m, "r_s": r_s, "rho_s": rho_s}
            lens_list.append(sub_param_dict)

        # Set source properties
        src_param_dict = {"profile": "Sersic", "theta_x_0": self.theta_x_0, "theta_y_0": self.theta_y_0, "S_tot": self.S_tot, "theta_e": self.theta_s_e, "n_srsc": 1}

        # Set observation and global properties
        observation_dict = {
            "n_x": n_xy,
            "n_y": n_xy,
            "theta_x_lims": (-self.coordinate_limit, self.coordinate_limit),
            "theta_y_lims": (-self.coordinate_limit, self.coordinate_limit),
            "exposure": exposure,
            "f_iso": self.f_iso,
        }

        global_dict = {"z_s": self.z_s, "z_l": self.z_l}

        # Inititalize lensing class and produce lensed image
        lsi = LensingSim(lens_list, [src_param_dict], global_dict, observation_dict)

        self.image = lsi.lensed_image()
        self.image_poiss = np.random.poisson(self.image)  # Poisson fluctuate
        self.image_poiss_psf = self._convolve_psf(self.image_poiss, fwhm_psf, pixel_size)  # Convolve with PSF

        # Augmented data
        self.joint_log_probs = ps.joint_log_probs
        self.joint_scores = ps.joint_scores

        # Optionally, compute derivatives of image wrt each subahlo mass (takes ~1s/subhalo)
        if calculate_msub_derivatives:
            self._calculate_derivs()

        # Optionally, compute derivatives of image wrt each subahlo mass (takes ~1s/subhalo)
        if calculate_sub_residuals:
            self._calculate_residuals()
Beispiel #11
0
def monte_tau(zeval, nrand=100, nHI=0.1, avg_ne=-2.6,
              sigma_ne=0.5, cosmo=None, lobs=50*u.cm, turb=None):
    """ Generate random draws of tau at a series of redshifts

    Parameters
    ----------
    zeval : ndarray
      Array of redshifts for evaluation
    nrand : int, optional
      Number of samples on NHI
    avg_ne : float, optional
      Average log10 electron density / cm**3
    sigma_ne : float, optional
      Error in log10 ne
    nHI : float, optional
      Fiducial value for n_HI;  used for DL value
    lobs : Quantity
      Wavelength for analysis
    turb : Turbulence object, optional
      Usually defined internally and that is the highly recommended approach
    cosmo : astropy.cosmology, optional
      Defaults to Planck15

    Returns
    -------
    rand_tau : ndarray  (nrand, nz)
      Random tau values reported in ms (but without explicit astropy Units)
    """
    # Init
    ne_param = dict(value=avg_ne, sigma=sigma_ne)  # Neeleman+15
    dla_fits = load_dla_fits()
    if cosmo is None:
        from astropy.cosmology import Planck15 as cosmo
    # Setup NHI
    lgNmax = np.linspace(20.3, 22., 10000)
    intfN = _int_dbl_pow(dla_fits['fN']['dpow'], lgNmax=lgNmax)
    # Spline
    interp_fN = interp1d(intfN/intfN[-1], lgNmax)#, kind='cubic')

    # Setup z
    zvals = np.linspace(0., 7., 10000)
    nz_s = _dla_nz(zvals)
    nz_s[0] = 0.

    # Turbulence
    if turb is None:
        turb = _init_dla_turb()
    f_ne=turb.ne
    zsource = 2.
    turb.set_rdiff(lobs)
    fiducial_tau = turb.temporal_smearing(lobs, zsource)
    # Take out the cosmology
    f_D_S = cosmo.angular_diameter_distance(zsource)
    f_D_L = cosmo.angular_diameter_distance(turb.zL)
    f_D_LS = cosmo.angular_diameter_distance_z1z2(turb.zL, zsource)
    fiducial_tau = fiducial_tau / f_D_LS / f_D_L * f_D_S * (1+turb.zL)**3  # ms/Mpc
    kpc_cm = (1*u.kpc).to('cm').value

    rand_tau = np.zeros((nrand, zeval.size))
    # Loop on zeval
    for ss,izeval in enumerate(zeval):
        avg_nz = _dla_nz(izeval)
        rn = np.random.poisson(avg_nz, size=nrand)
        ndla = np.sum(rn)
        if ndla == 0:
            continue
        # Get random NHI
        rval = np.random.uniform(size=ndla)
        rNHI = interp_fN(rval)
        DL = 10.**rNHI / nHI / kpc_cm
        # Get random z
        imin = np.argmin(np.abs(zvals-izeval))
        interp_z = interp1d(nz_s[0:imin]/nz_s[imin-1], zvals[0:imin])#, kind='cubic')
        rval = np.random.uniform(size=ndla)
        rz = interp_z(rval)
        # Cosmology
        D_S = cosmo.angular_diameter_distance(izeval)
        D_L = cosmo.angular_diameter_distance(rz)
        D_LS = cosmo.angular_diameter_distance_z1z2(rz, izeval)
        # Get random n_e
        rne = 10.**(ne_param['value'] + ne_param['sigma']*np.random.normal(size=ndla))
        # Calculate (scale)
        rtau = fiducial_tau * (D_LS * D_L / D_S) * (rne/f_ne.to('cm**-3').value)**2 / (1+rz)**3
        # Generate, fill
        taus = np.zeros((nrand, np.max(rn)))
        kk = 0
        for jj,irn in enumerate(rn):
            if irn > 0:
                taus[jj,0:irn] = rtau[kk:kk+irn]
                kk += irn
        # Finish -- add in quadrature
        final_tau = np.sqrt(np.sum(taus**2, axis=1))
        # Save
        rand_tau[:,ss] = final_tau

    # Return
    return rand_tau
Beispiel #12
0
yim = np.arange(-3,3,.03)

xim,yim = np.meshgrid(xim,yim)

zLens,zSource = 0.8,5.656
xLens,yLens = 0.,0.
MLens,eLens,PALens = 2.87e11,0.5,90.
xSource,ySource,FSource,sSource = 0.216,-0.24,0.023,0.074

Lens = vl.SIELens(zLens,xLens,yLens,MLens,eLens,PALens)
Shear= vl.ExternalShear(0.,0.)
lens = [Lens,Shear]
Source = vl.GaussSource(zSource,True,xSource,ySource,FSource,sSource)
Dd = cosmo.angular_diameter_distance(zLens).value
Ds = cosmo.angular_diameter_distance(zSource).value
Dds = cosmo.angular_diameter_distance_z1z2(zLens,zSource).value
caustics = vl.get_caustics(lens,Dd,Ds,Dds)

xsource,ysource = vl.LensRayTrace(xim,yim,lens,Dd,Ds,Dds)


f = pl.figure()
ax = f.add_subplot(111,aspect='equal')
pl.subplots_adjust(bottom=0.25,top=0.98)

ax.plot(xsource,ysource,'b-')
for caustic in caustics:
      ax.plot(caustic[:,0],caustic[:,1],'k-')

# Put in a bunch of sliders to control lensing parameters
Beispiel #13
0
def plot_images(data,
                mcmcresult,
                returnimages=False,
                plotcombined=False,
                plotall=False,
                imsize=256,
                pixsize=0.2,
                taper=0.,
                **kwargs):
    """
      Create a five-panel figure from data and chains,
      showing data, best-fit model, residuals, high-res image, source plane

      Inputs:
      data:
            The visdata object(s) to be imaged. If more than
            one is passed, they'll be imaged/differenced separately.
      chains:
            A result from running LensModelMCMC.

      returnimages: bool, optional
            If True, will also return a list of numpy arrays
            containing the imaged data, interpolated model, and full-res model.
            Default is False.
      
      plotcombined: bool, optional, default False
            If True, plots only a single row of images, after combining all datasets
            in `data' and applying any necessary rescaling/shifting contained in
            `mcmcresult'.
      
      plotall: bool, optional, default False
            If True, plots each dataset in its own row *and* the combined dataset in
            an extra row.

      Returns:
      If returnimages is False:
      f, axarr:
            A matplotlib figure and array of Axes objects.

      If returnimages is True:
      f,axarr,imagelist:
            Same as above; imagelist is a list of length (# of datasets),
            containing four arrays each, representing the data,
            interpolated model, full-resolution model, and source plane.
      """

    limits = kwargs.pop('limits', [
        -imsize * pixsize / 2., +imsize * pixsize / 2., -imsize * pixsize / 2.,
        +imsize * pixsize / 2.
    ])
    cmap = kwargs.pop('cmap', cm.Greys)
    mapcontours = kwargs.pop('mapcontours', np.delete(np.arange(-21, 22, 3),
                                                      7))
    rescontours = kwargs.pop('rescontours',
                             np.array([-6, -5, -4, -3, -2, 2, 3, 4, 5, 6]))
    level = kwargs.pop('level', None)
    logmodel = kwargs.pop('logmodel', False)

    datasets = list(np.array([data]).flatten())

    # shorthand for later
    c = copy.deepcopy(mcmcresult['chains'])

    # Now all these things are saved separately, don't have to do the BS above
    lens = mcmcresult['best-fit']['lens']
    source = mcmcresult['best-fit']['source']
    scaleamp = mcmcresult['best-fit']['scaleamp'] if 'scaleamp' in mcmcresult[
        'best-fit'].keys() else np.ones(len(datasets))
    shiftphase = mcmcresult['best-fit'][
        'shiftphase'] if 'shiftphase' in mcmcresult['best-fit'].keys(
        ) else np.zeros((len(datasets), 2))
    sourcedatamap = mcmcresult[
        'sourcedatamap'] if 'sourcedatamap' in mcmcresult.keys(
        ) else [None] * len(datasets)
    modelcal = mcmcresult['modelcal'] if 'modelcal' in mcmcresult.keys(
    ) else [False] * len(datasets)

    if plotall:
        f, axarr = plt.subplots(len(datasets) + 1,
                                5,
                                figsize=(14, 4 * (len(datasets) + 1)))
        axarr = np.atleast_2d(axarr)
        images = [[] for _ in range(len(datasets) + 1)]
        if sourcedatamap[0] is not None:
            warnings.warn(
                "sourcedatamap[0] is not None. Are you sure you want plotall=True?"
            )
        sourcedatamap.append(None)
        f.subplots_adjust(left=0.05, bottom=0.05, top=0.95, right=0.99)
    elif plotcombined:
        f, axarr = plt.subplots(1, 5, figsize=(14, 4))
        axarr = np.atleast_2d(axarr)
        images = [[]]
        if sourcedatamap[0] is not None:
            warnings.warn(
                "sourcedatamap[0] is not None, and has been set to None. Are you sure you want plotcombined=True? This could break the source plane plot."
            )
        sourcedatamap = [None]
        f.subplots_adjust(left=0.05, bottom=0.05, top=0.95, right=0.99)
    else:
        f, axarr = plt.subplots(len(datasets),
                                5,
                                figsize=(14, 4 * len(datasets)))
        axarr = np.atleast_2d(axarr)
        images = [[] for _ in range(len(datasets))]  # effing mutable lists.
        f.subplots_adjust(left=0.05, bottom=0.05, top=0.95, right=0.99)

    plotdata, plotinterp = [], []

    for i, dset in enumerate(datasets):
        # Get us some coordinates.
        xmap,ymap,xemit,yemit,ix = GenerateLensingGrid(datasets,mcmcresult['xmax'],\
              mcmcresult['highresbox'],mcmcresult['fieldres'],mcmcresult['emitres'])

        # Create model image
        immap,_ = create_modelimage(lens,source,xmap,ymap,xemit,yemit,\
              ix,sourcedatamap=sourcedatamap[i])

        # And interpolate onto uv-coords of dataset
        interpdata = fft_interpolate(dset,immap,xmap,ymap,ug=None,\
              scaleamp=scaleamp[i],shiftphase=shiftphase[i])

        if modelcal[i]:
            selfcal, _ = model_cal(dset, interpdata)

        else:
            selfcal = copy.deepcopy(dset)

        plotdata.append(selfcal)
        plotinterp.append(interpdata)

    if plotall:
        plotdata.append(concatvis(plotdata))
        plotinterp.append(concatvis(plotinterp))
    elif plotcombined:
        plotdata = [concatvis(plotdata)]
        plotinterp = [concatvis(plotinterp)]

    for row in range(axarr.shape[0]):

        # Image the data
        imdata = uvimageslow(plotdata[row], imsize, pixsize, taper)
        # Image the model
        immodel = uvimageslow(plotinterp[row], imsize, pixsize, taper)
        # And the residuals
        imdiff = imdata - immodel

        if returnimages:
            images[row].append(imdata)
            images[row].append(immodel)

        # Plot everything up
        ext = [
            -imsize * pixsize / 2., imsize * pixsize / 2.,
            -imsize * pixsize / 2., imsize * pixsize / 2.
        ]
        # Figure out what to use as the noise level; sum of weights if no user-supplied value
        if level is None: s = ((plotdata[row].sigma**-2.).sum())**-0.5
        else:
            try:
                s = [e for e in level][i]
            except TypeError:
                s = float(level)

        print("Data - Model rms: {0:0.3e}".format(imdiff.std()))
        axarr[row, 0].imshow(imdata,
                             interpolation='nearest',
                             extent=ext,
                             cmap=cmap)
        axarr[row, 0].contour(imdata,
                              extent=ext,
                              colors='k',
                              origin='image',
                              levels=s * mapcontours)
        axarr[row, 0].set_xlim(limits[0], limits[1])
        axarr[row, 0].set_ylim(limits[2], limits[3])
        axarr[row,1].imshow(immodel,interpolation='nearest',extent=ext,cmap=cmap,\
              vmin=imdata.min(),vmax=imdata.max())
        axarr[row, 1].contour(immodel,
                              extent=ext,
                              colors='k',
                              origin='image',
                              levels=s * mapcontours)
        axarr[row, 1].set_xlim(limits[0], limits[1])
        axarr[row, 1].set_ylim(limits[2], limits[3])
        axarr[row,2].imshow(imdiff,interpolation='nearest',extent=ext,cmap=cmap,\
              vmin=imdata.min(),vmax=imdata.max())
        axarr[row, 2].contour(imdiff,
                              extent=ext,
                              colors='k',
                              origin='image',
                              levels=s * rescontours)
        axarr[row, 2].set_xlim(limits[0], limits[1])
        axarr[row, 2].set_ylim(limits[2], limits[3])
        if np.log10(s) < -6.: sig, unit = 1e9 * s, 'nJy'
        elif np.log10(s) < -3.: sig, unit = 1e6 * s, '$\mu$Jy'
        elif np.log10(s) < 0.: sig, unit = 1e3 * s, 'mJy'
        else: sig, unit = s, 'Jy'
        axarr[row, 2].text(0.05,
                           0.05,
                           "Data 1$\sigma$ = {0:.1f}{1:s}".format(sig, unit),
                           transform=axarr[row, 2].transAxes,
                           bbox=dict(fc='w'))

        # For the last two panels, give the apparent emission at higher resolution
        # and the intrinsic source plane structure.
        # Create model image at higher res, remove unlensed sources
        src = [src for src in source if src.lensed]
        imemit,_ = create_modelimage(lens,src,xemit,yemit,xemit,yemit,\
              [0,xemit.shape[1],0,xemit.shape[0]],sourcedatamap=sourcedatamap[row])
        images[row].append(imemit)

        xcen = center_of_mass(imemit)[1] * (xemit[0, 1] -
                                            xemit[0, 0]) + xemit.min()
        ycen = -center_of_mass(imemit)[0] * (xemit[0, 1] -
                                             xemit[0, 0]) + yemit.max()
        dx = 0.5 * (xemit.max() - xemit.min())
        dy = 0.5 * (yemit.max() - yemit.min())

        if logmodel:
            norm = SymLogNorm(
                0.01 * imemit.max()
            )  #imemit = np.log10(imemit); vmin = imemit.min()-2.
        else:
            norm = None  #vmin = imemit.min()
        axarr[row,3].imshow(imemit,interpolation='nearest',\
              extent=[xemit.min(),xemit.max(),yemit.min(),yemit.max()],cmap=cmap,norm=norm)

        axarr[row, 3].set_xlim(xcen - dx, xcen + dx)
        axarr[row, 3].set_ylim(ycen - dy, ycen + dy)

        # And create source plane using the exact grids the code used during fitting.
        imsource = np.zeros(xemit.shape)
        for s in src:
            imsource += SourceProfile(xemit, yemit, s,
                                      lens) * (xemit[0, 1] - xemit[0, 0])**2.
        images[row].append(imsource)

        xcen = center_of_mass(imsource)[1] * (xemit[0, 1] -
                                              xemit[0, 0]) + xemit.min()
        ycen = -center_of_mass(imemit)[0] * (xemit[0, 1] -
                                             xemit[0, 0]) + yemit.max()
        dx = 0.5 * (xemit.max() - xemit.min())
        dy = 0.5 * (yemit.max() - yemit.min())

        axarr[row, 4].imshow(
            imsource,
            interpolation='nearest',
            extent=[xemit.min(),
                    xemit.max(),
                    yemit.min(),
                    yemit.max()],
            cmap=cmap,
            norm=SymLogNorm(0.01 * imsource.max()),
            origin='lower')

        axarr[row, 4].set_xlim(xcen - dx, xcen + dx)
        axarr[row, 4].set_ylim(ycen - dy, ycen + dy)

        # Need to precalculate distances to get caustics
        Dd = Planck15.angular_diameter_distance(lens[0].z).value
        Ds = Planck15.angular_diameter_distance(source[0].z).value
        Dds = Planck15.angular_diameter_distance_z1z2(lens[0].z,
                                                      source[0].z).value
        caustics = get_caustics(lens,
                                Dd,
                                Ds,
                                Dds,
                                highresbox=mcmcresult['highresbox'],
                                numres=mcmcresult['emitres'])
        for caustic in caustics:
            axarr[row, 3].plot(caustic[:, 0],
                               caustic[:, 1],
                               ls='-',
                               marker='',
                               lw=1,
                               color='r')
            axarr[row, 4].plot(caustic[:, 0],
                               caustic[:, 1],
                               ls='-',
                               marker='',
                               lw=1,
                               color='r')

        s = imdiff.std()
        if np.log10(s) < -6.: sig, unit = 1e9 * s, 'nJy'
        elif np.log10(s) < -3.: sig, unit = 1e6 * s, '$\mu$Jy'
        elif np.log10(s) < 0.: sig, unit = 1e3 * s, 'mJy'
        else: sig, unit = s, 'Jy'

        # Label some axes and such
        axarr[row, 0].set_title(plotdata[row].filename + '\nDirty Image')
        axarr[row, 1].set_title('Model Dirty Image')
        axarr[row,
              2].set_title('Residual Map rms={0:.1f}{1:s}'.format(sig, unit))
        if logmodel: axarr[row, 3].set_title('High-res Model (log-scale)')
        else: axarr[row, 3].set_title('High-res Model')
        axarr[row, 4].set_title('Source Plane Model')

    if returnimages: return f, axarr, images
    else: return f, axarr