def timedelay_magnification(mu_map, phi_map, dsx_arc, Ncells, lp1, lp2, alpha1, alpha2, SrcPosSky, zs, zl, cosmo): """ Calculate Photon-travel-time and Magnification of strong lensed supernovae Input: lp1, lp2: lens place grid coordinates Output: len(mu): number of multiple images of supernova delta_t: Time it takes for photon to cover distance source-observer mu: luminosity magnification of source """ # Mapping light rays from image plane to source plan [sp1, sp2] = [lp1 - alpha1, lp2 - alpha2] #yi1,yi2[arcsec] # Source position [arcsec] #x = SrcPosSky[0]*u.Mpc #y = SrcPosSky[1]*u.Mpc #z = SrcPosSky[2]*u.Mpc #if (y == 0.) and (z == 0.): # beta1 = 1e-3 # beta2 = 1e-3 #else: # beta1 = ((y/x)*u.rad).to_value('arcsec') # beta2 = ((z/x)*u.rad).to_value('arcsec') beta1 = 1e-3 beta2 = 1e-3 #print("Wait here mapping_triangles") theta1, theta2 = cf.call_mapping_triangles([beta1, beta2], lp1, lp2, sp1, sp2) # calculate magnifications of lensed Supernovae #print("Wait here inverse_cic_single") mu = cf.call_inverse_cic_single(mu_map, 0.0, 0.0, theta1, theta2, dsx_arc) # calculate time delays of lensed Supernovae in Days prts = cf.call_inverse_cic_single(phi_map, 0.0, 0.0, theta1, theta2, dsx_arc) Kc = ((1.0+zl)/const.c.to('Mpc/s') * \ (cosmo.angular_diameter_distance(zl) * \ cosmo.angular_diameter_distance(zs) / \ (cosmo.angular_diameter_distance(zs) - \ cosmo.angular_diameter_distance(zl)))).to('sday').value delta_t = Kc*(0.5*((theta1 - beta1)**2.0 + (theta2 - beta2)**2.0) - prts)/cf.apr**2 beta = [beta1, beta2] theta = [theta1, theta2] return len(mu), delta_t, mu, theta, beta
def timedelay_magnification(mu_map, phi_map, dsx_arc, Ncells, lp1, lp2, alpha1, alpha2, SrcPosSky, zs, zl, cosmo): """ Calculate Photon-travel-time and Magnification of strong lensed supernovae Input: FOV: Field-of-View [Mpc] Ncells: number of cells for grid on FOV kappa: convergence map SrcPosSky: Position of Source relative to Lens [Mpc] zs: Redshift of Source zl: Redshift of Lens cosmo: Cosmology Output: len(mu): number of multiple images of supernova delta_t: Time it takes for photon to cover distance source-observer mu: luminosity magnification of source """ # Mapping light rays from image plane to source plan [sp1, sp2] = [lp1 - alpha1, lp2 - alpha2] #yi1,yi2[arcsec] # Source position [arcsec] x = SrcPosSky[0]*u.Mpc y = SrcPosSky[1]*u.Mpc z = SrcPosSky[2]*u.Mpc beta1 = ((y/x)*u.rad).to_value('arcsec') beta2 = ((z/x)*u.rad).to_value('arcsec') theta1, theta2 = cf.call_mapping_triangles([beta1, beta2], lp1, lp2, sp1, sp2) # calculate magnifications of lensed Supernovae mu = cf.call_inverse_cic_single(mu_map, 0.0, 0.0, theta1, theta2, dsx_arc) # calculate time delays of lensed Supernovae in Days prts = cf.call_inverse_cic_single(phi_map, 0.0, 0.0, theta1, theta2, dsx_arc) Kc = ((1.0+zl)/const.c.to('Mpc/s') * \ (cosmo.angular_diameter_distance(zl) * \ cosmo.angular_diameter_distance(zs) / \ (cosmo.angular_diameter_distance(zs) - \ cosmo.angular_diameter_distance(zl)))).to('sday').value delta_t = Kc*(0.5*((theta1 - beta1)**2.0 + (theta2 - beta2)**2.0) - prts)/cf.apr**2 beta = [beta1, beta2] theta = [theta1, theta2] return len(mu), delta_t, mu, theta, beta
def timedelay_magnification(mu_map, phi_map, dsx_arc, Ncells, lp1, lp2, alpha1, alpha2, beta, zs, zl, cosmo): """ Input: mu_map: 2D magnification map phi_map: 2D potential map dsx_arc: cell size in arcsec Ncells: number of cells lp1, lp2: lens place grid coordinates alpha1, alpha2: 2D deflection map SrcPosSky: source position in Mpc zs: source redshift zl: lens redshift Output: len(mu): number of multiple images of supernova delta_t: Time it takes for photon to cover distance source-observer mu: luminosity magnification of source """ # Mapping light rays from image plane to source plan [sp1, sp2] = [lp1 - alpha1, lp2 - alpha2] #[arcsec] theta1, theta2 = cf.call_mapping_triangles([beta[0], beta[1]], lp1, lp2, sp1, sp2) # calculate magnifications of lensed Supernovae mu = cf.call_inverse_cic_single(mu_map, 0.0, 0.0, theta1, theta2, dsx_arc) # calculate time delays of lensed Supernovae in Days prts = cf.call_inverse_cic_single(phi_map, 0.0, 0.0, theta1, theta2, dsx_arc) Kc = ((1.0+zl)/const.c.to('Mpc/s') * \ (cosmo.angular_diameter_distance(zl) * \ cosmo.angular_diameter_distance(zs) / \ (cosmo.angular_diameter_distance(zs) - \ cosmo.angular_diameter_distance(zl)))).to('sday').value delta_t = Kc*(0.5*((theta1 - beta[0])**2.0 + \ (theta2 - beta[1])**2.0) - prts)/cf.apr**2 theta = np.array([theta1, theta2]).T return len(mu), delta_t, mu, theta
def make_lensing_mocks(self, nsrcs=Nz_Chang2014, zs=None, vis_shears=False): """ Performs interpolation on ray tracing maps, writing the result to an HDF file, the location of which is specified in `self.inp.outputs_path`. Note: the output files will be closed after this function executes, so if needed to be called again, this object will need to be re-initialized. Parameters ---------- nsrcs : int or callable or None If passed as an int, this is the number of sources to randomly place in the fov. This is useful if creating a mock at one source plane; if using many source planes, then the lower redshift will effectively be weighted more strongly (nsrcs is constant while the angular scale grows). If a callable, then a function to compute the number distribution N(z) should be given, and will be called at each source plane redshift, where galaxies will be populated randomly in angular space, with their count inferred from N(z). The callable is expected to return N(z) in armin^-2 Defaults to Nz_Chang2014(). zs : float array or None Redshift edges of source planes to include. If None, use all source plaes given in ray-tracing outputs for the halo specified in self.inp. Defaults to None. theta1 : float array or None **DEPRECATED** azimuthal angular coordinate of the sources, in arcsec. If None, then nsrcs is assumed to have been passed, and theta1 will be generated from a uniform random distribution on the fov. If not None, then nsrcs should be None, else will throw an error. Defaults to None. theta2 : float array or None **DEPRECATED** coalitude angular coordinate of the sources, in arcsec. If None, then nsrcs is assumed to have been passed, and theta1 will be generated from a uniform random distribution on the fov. If not None, then nsrcs should be None, else will throw an error. Defaults to None. """ self.print( '\n ---------- creating lensing mocks for halo {} ---------- '. format(self.inp.halo_id)) assert self.raytrace_file is not None, "read_raytrace_planes() must be called before interpolation" # get source plane redshift edges if not passed if (zs is None): zs = [0.0] zs = np.hstack([ zs, np.squeeze([ self.raytrace_file[key]['zs'][:] for key in self.source_plane_keys ]) ]) # define interpolation points # if nsrcs is callable, calulate N(z) and randomly populate source planes # if nsrcs is an int, randomly populate source planes with uniform density if hasattr(nsrcs, '__call__'): box_arcmin2 = (self.inp.bsz_arc / 60)**2 Nz = (nsrcs(zs) * box_arcmin2).astype(int) ys1_arrays = np.array([ np.random.random(nn) * self.inp.bsz_arc - self.inp.bsz_arc * 0.5 for nn in Nz ]) ys2_arrays = np.array([ np.random.random(nn) * self.inp.bsz_arc - self.inp.bsz_arc * 0.5 for nn in Nz ]) else: ys1_arrays = np.array([ np.random.random(nsrcs) * self.inp.bsz_arc - self.inp.bsz_arc * 0.5 for i in range(len(zs)) ]) ys2_arrays = np.array([ np.random.random(nsrcs) * self.inp.bsz_arc - self.inp.bsz_arc * 0.5 for i in range(len(zs)) ]) self.print('created out file {}'.format(self.out_file.filename)) self.print('reading {}'.format(self.raytrace_file.filename)) # loop over source planes for i in range(len(self.source_plane_keys)): zsp = zs[i] zkey = self.source_plane_keys[i] self.print( '-------- placing {} sources at source plane {} --------'. format(len(ys1_arrays[i]), zkey)) # get positions at this source plane ys1_array = ys1_arrays[i] ys2_array = ys2_arrays[i] af1 = self.raytrace_file[zkey]['alpha1'][:] af2 = self.raytrace_file[zkey]['alpha2'][:] kf0 = self.raytrace_file[zkey]['kappa0'][:] sf1 = self.raytrace_file[zkey]['shear1'][:] sf2 = self.raytrace_file[zkey]['shear2'][:] # Deflection Angles and lensed Positions yf1 = self.xx1 - af1 yf2 = self.xx2 - af2 xr1_array, xr2_array = cf.call_mapping_triangles_arrays_omp( ys1_array, ys2_array, self.xx1, self.xx2, yf1, yf2) # xr1_array, xr2_array = ys1_array, ys2_array # Update Lensing Signals of Lensed Positions kr0_array = cf.call_inverse_cic_single(kf0, 0.0, 0.0, xr1_array, xr2_array, self.inp.dsx_arc) sr1_array = cf.call_inverse_cic_single(sf1, 0.0, 0.0, xr1_array, xr2_array, self.inp.dsx_arc) sr2_array = cf.call_inverse_cic_single(sf2, 0.0, 0.0, xr1_array, xr2_array, self.inp.dsx_arc) mfa = cf.alphas_to_mu(af1, af2, self.inp.bsz_arc, self.inp.nnn) mra_array = cf.call_inverse_cic_single(mfa, 0.0, 0.0, xr1_array, xr2_array, self.inp.dsx_arc) # Save Outputs self.out_file.create_group(zkey) self.out_file[zkey]['zs'] = np.atleast_1d(zsp).astype('float32') self.out_file[zkey]['xr1'] = xr1_array.astype('float32') self.out_file[zkey]['xr2'] = xr2_array.astype('float32') self.out_file[zkey]['kr0'] = kr0_array.astype('float32') self.out_file[zkey]['sr1'] = sr1_array.astype('float32') self.out_file[zkey]['sr2'] = sr2_array.astype('float32') self.out_file[zkey]['mra'] = mra_array.astype('float32') if vis_shears: self.shear_vis_mocks(xr1_array, xr2_array, sr1_array, sr2_array, kf0) self.raytrace_file.close() self.out_file.close() self.print('done')