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.05,'$\\mu$ = {0:.2f}'.format(mu),transform=ax.transAxes) for i in range(caustics.shape[0]): ax.plot(caustics[i,0,:],caustics[i,1,:],'k-') f.canvas.draw_idle()
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 WMAP9 if np.any((Dd is None,Ds is None, Dds is None)): from astropy.cosmology import WMAP9 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 conversion_factor(cc): '''cc is a ClusterConfig object, defined in cluster_config.py''' alt_cosmo = FlatLambdaCDM(70, cc.wl_omega_m) dd1 = cosmo.angular_diameter_distance(cc.redshift) ds1 = cosmo.angular_diameter_distance(z_src_infinity) dds1 = cosmo.angular_diameter_distance_z1z2(cc.redshift, z_src_infinity) dd2 = alt_cosmo.angular_diameter_distance(cc.redshift) ds2 = alt_cosmo.angular_diameter_distance(cc.src_redshift) dds2 = alt_cosmo.angular_diameter_distance_z1z2(cc.redshift, cc.src_redshift) crit_surf_density_1 = lensing_crit_surf_density(ds1, dd1, dds1) crit_surf_density_2 = lensing_crit_surf_density(ds2, dd2, dds2) return crit_surf_density_2 / crit_surf_density_1
def lens_astropy(): import pylab as pl from astropy.cosmology import WMAP9 zl = np.linspace(0.01, 1.9, 100) zs = 2. wa = [] wc = [] angs = WMAP9.angular_diameter_distance(zs).value chis = WMAP9.comoving_distance(zs).value for zi in zl: angl = WMAP9.angular_diameter_distance(zi).value angls = WMAP9.angular_diameter_distance_z1z2(zi,zs).value chil = WMAP9.comoving_distance(zi).value chils = WMAP9.comoving_distance(zs).value-WMAP9.comoving_distance(zi).value wa.append(angl * angls / angs) wc.append(chil * chils / chis / (1+zi)) pl.plot(zl, wa) pl.plot(zl, wc, ls='--') pl.show()
def lens_astropy(): import pylab as pl from astropy.cosmology import WMAP9 zl = np.linspace(0.01, 1.9, 100) zs = 2. wa = [] wc = [] angs = WMAP9.angular_diameter_distance(zs).value chis = WMAP9.comoving_distance(zs).value for zi in zl: angl = WMAP9.angular_diameter_distance(zi).value angls = WMAP9.angular_diameter_distance_z1z2(zi, zs).value chil = WMAP9.comoving_distance(zi).value chils = WMAP9.comoving_distance(zs).value - WMAP9.comoving_distance( zi).value wa.append(angl * angls / angs) wc.append(chil * chils / chis / (1 + zi)) pl.plot(zl, wa) pl.plot(zl, wc, ls='--') pl.show()
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.CausticsSIE(newLens,newDd,newDs,newDds,newShear) ax.cla() ax.plot(xsource,ysource,'b-') for i in range(caustics.shape[0]): ax.plot(caustics[i,0,:],caustics[i,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()
def microcaustic_field_to_curve(field, time, zl, zs, velocity=(10**4)*(u.kilometer/u.s), M=(1*u.solMass).to(u.kg), width_in_einstein_radii=10, loc='Random', plot=False, ax=None, showCurve=True, rescale=True): """ Convolves an expanding photosphere (achromatic disc) with a microcaustic to generate a magnification curve. Parameters ---------- field: :class:`numpy.ndarray` An opened fits file of a microcaustic, can be generated by realizeMicro time: :class:`numpy.array` Time array you want for microlensing magnification curve, explosion time is 0 zl: float redshift of the lens zs: float redshift of the source velocity: float* :class:`astropy.units.Unit` The average velocity of the expanding photosphere M: float* :class:`~astropy.units.Unit` The mass of the deflector width_in_einstein_radii: float The width of your map in units of Einstein radii loc: str or tuple Random is defualt for location of the supernova, or pixel (x,y) coordiante can be specified plot: bool If true, plots the expanding photosphere on the microcaustic ax: `~matplotlib.pyplot.axis` An optional axis object to plot on. If you want to show the curve, this should be a list like this: [main_ax,lower_ax] showCurve: bool If true, the microlensing curve is plotted below the microcaustic rescale: bool If true, assumes image needs to be rescaled: (x-1024)/256 Returns ------- time: :class:`numpy.array` The time array for the magnification curve dmag: :class:`numpy.array` The magnification curve. """ D = cosmo.angular_diameter_distance_z1z2( zl, zs)*cosmo.angular_diameter_distance(zs)/cosmo.angular_diameter_distance(zl) D = D.to(u.m) try: M.to(u.kg) except: print('Assuming mass is in kg.') einsteinRadius = np.sqrt(4*const.G*M*D/const.c**2) einsteinRadius = einsteinRadius.to(u.kilometer) try: velocity.to(u.kilometer/u.s) except: print('Assuming velocity is in km/s.') velocity *= (u.kilometer/u.s) h, w = field.shape height = width_in_einstein_radii*einsteinRadius.value width = width_in_einstein_radii*einsteinRadius.value pixwidth = width/w pixheight = height/h if pixwidth != pixheight: print('Hmm, you are not using squares...') sys.exit() maxRadius = ((np.max(time)*u.d).to(u.s))*velocity maxRadius = maxRadius.value maxx = int(math.floor(maxRadius/pixwidth)) maxy = int(math.floor(maxRadius/pixheight)) mlimage = field[maxx:-maxx][maxy:-maxy] if loc == 'Random' or not isinstance(loc, (list, tuple)): loc = (int(np.random.uniform(maxx, w-maxx)), int(np.random.uniform(maxy, h-maxy))) tempTime = np.array([((x*u.d).to(u.s)).value for x in time]) snSize = velocity.value*tempTime/pixwidth dmag = mu_from_image(field, loc, snSize, 'disk', plot, time, ax, showCurve, rescale, width_in_einstein_radii) return(time, dmag)
def microcaustic_field_to_curve(field, time, zl, zs, velocity=(10**4) * (u.kilometer / u.s), M=(1 * u.solMass).to(u.kg), loc='Random', plot=False): """Convolves an expanding photosphere (achromatic disc) with a microcaustic to generate a magnification curve. Parameters ---------- field: :class:`numpy.ndarray` An opened fits file of a microcaustic, can be generated by realizeMicro time: :class:`numpy.array` Time array you want for microlensing magnification curve, explosion time is 0 zl: float redshift of the lens zs: float redshift of the source velocity: float* :class:`astropy.units.Unit` The average velocity of the expanding photosphere M: float* :class:`astropy.units.Unit` The mass of the deflector loc: str or tuple Random is defualt for location of the supernova, or pixel (x,y) coordiante can be specified plot: Boolean If true, plots the expanding photosphere on the microcaustic Returns ------- time: :class:`numpy.array` The time array for the magnification curve dmag: :class:`numpy.array` The magnification curve. """ D = cosmo.angular_diameter_distance_z1z2( zl, zs) * cosmo.angular_diameter_distance( zs) / cosmo.angular_diameter_distance(zl) D = D.to(u.m) try: M.to(u.kg) except: print('Assuming mass is in kg.') einsteinRadius = np.sqrt(4 * const.G * M * D / const.c**2) einsteinRadius = einsteinRadius.to(u.kilometer) try: velocity.to(u.kilometer / u.s) except: print('Assuming velocity is in km/s.') velocity *= (u.kilometer / u.s) #mlimage=fits.getdata(field) h, w = field.shape height = 10 * einsteinRadius.value width = 10 * einsteinRadius.value #print(10*einsteinRadius) #center=(width/2,height/2) pixwidth = width / w pixheight = height / h if pixwidth != pixheight: print('Hmm, you are not using squares...') sys.exit() maxRadius = ((np.max(time) * u.d).to(u.s)) * velocity maxRadius = maxRadius.value maxx = int(math.floor(maxRadius / pixwidth)) maxy = int(math.floor(maxRadius / pixheight)) mlimage = field[maxx:-maxx][maxy:-maxy] if loc == 'Random' or not isinstance(loc, (list, tuple)): loc = (int(np.random.uniform(maxx, w - maxx)), int(np.random.uniform(maxy, h - maxy))) tempTime = np.array([((x * u.d).to(u.s)).value for x in time]) snSize = velocity.value * tempTime / pixwidth dmag = mu_from_image(field, loc, snSize, 'disk', plot, time) return (time, dmag)
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,sSource,nSource,arSource,PAsource = 0.216,0.24,0.02,0.1,0.8,0.7,120.-90 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,sSource,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.