def sim_image(self, info_dict): """ Simulate an image based on specifications in sim_dict :param info_dict: A single element of the output form Organizer.breakup() """ output_image = [] if self.return_planes: output_source, output_lens, output_point_source, output_noise = [], [], [], [] output_metadata = [] #set the cosmology cosmology_info = ['H0', 'Om0', 'Tcmb0', 'Neff', 'm_nu', 'Ob0'] cosmo = FlatLambdaCDM(**dict_select_choose(list(info_dict.values())[0], cosmology_info)) for band, sim_dict in info_dict.items(): ### Geometry-independent image properties # Single Band Info single_band_info = ['read_noise', 'pixel_scale', 'ccd_gain', 'exposure_time', 'sky_brightness', 'seeing', 'magnitude_zero_point', 'num_exposures', 'data_count_unit', 'background_noise'] kwargs_single_band = dict_select_choose(sim_dict, single_band_info) # Extinction extinction_class = None #figure this out later # Numerics -- only use single number kwargs numerics_info = ['supersampling_factor', 'compute_mode', 'supersampling_convolution', 'supersampling_kernel_size', 'point_source_supersampling_factor', 'convolution_kernel_size'] kwargs_numerics = dict_select_choose(sim_dict, numerics_info) ### Geometry-dependent image properties # Dictionary for physical model kwargs_model = {'lens_model_list': [], # list of lens models to be used 'lens_redshift_list': [], # list of redshift of the deflections 'lens_light_model_list': [], # list of unlensed light models to be used 'source_light_model_list': [], # list of extended source models to be used 'source_redshift_list': [], # list of redshfits of the sources in same order as source_light_model_list 'point_source_model_list': [], # list of point source models 'cosmo': cosmo, 'z_source': 0.0} # Lists for model kwargs kwargs_source_list, kwargs_lens_model_list, kwargs_lens_light_list, kwargs_point_source_list = [], [], [], [] for plane_num in range(1, sim_dict['NUMBER_OF_PLANES'] + 1): for obj_num in range(1, sim_dict['PLANE_{0}-NUMBER_OF_OBJECTS'.format(plane_num)] + 1): prefix = 'PLANE_{0}-OBJECT_{1}-'.format(plane_num, obj_num) ### Point sources if sim_dict[prefix + 'HOST'] != 'None': # Foreground objects if sim_dict[prefix + 'HOST'] == 'Foreground': kwargs_model['point_source_model_list'].append('UNLENSED') ps_info = ['PLANE_{0}-OBJECT_{1}-{2}'.format(plane_num, obj_num, x) for x in ['ra_image', 'dec_image', 'magnitude']] ps_dict_info = dict_select(sim_dict, ps_info) kwargs_point_source_list.append({'ra_image': [ps_dict_info[prefix + 'ra_image']], 'dec_image': [ps_dict_info[prefix + 'dec_image']], 'magnitude': [ps_dict_info[prefix + 'magnitude']]}) # Real point sources else: if plane_num < sim_dict['NUMBER_OF_PLANES']: # point sources in the lens kwargs_model['point_source_model_list'].append('LENSED_POSITION') ps_info = ['PLANE_{0}-OBJECT_{1}-{2}'.format(plane_num, obj_num, x) for x in ['ra', 'dec', 'magnitude']] ps_dict_info = dict_select(sim_dict, ps_info) kwargs_point_source_list.append({'ra_image': [ps_dict_info[prefix + 'ra']], 'dec_image': [ps_dict_info[prefix + 'dec']], 'magnitude': [ps_dict_info[prefix + 'magnitude']]}) elif plane_num == sim_dict['NUMBER_OF_PLANES']: # point sources in the source plane kwargs_model['point_source_model_list'].append('SOURCE_POSITION') ps_info = ['PLANE_{0}-OBJECT_{1}-{2}'.format(plane_num, obj_num, x) for x in ['ra', 'dec', 'magnitude']] ps_dict_info = dict_select(sim_dict, ps_info) kwargs_point_source_list.append({'ra_source': ps_dict_info['PLANE_{0}-OBJECT_{1}-ra'.format(plane_num, obj_num)], 'dec_source': ps_dict_info['PLANE_{0}-OBJECT_{1}-dec'.format(plane_num, obj_num)], 'magnitude': ps_dict_info['PLANE_{0}-OBJECT_{1}-magnitude'.format(plane_num, obj_num)]}) else: #should never get here assert False # the number of profiles will be zero for point sources, so just skip ahead continue ### Model keywords # All planes except last one - treat as lens if plane_num < sim_dict['NUMBER_OF_PLANES']: for light_profile_num in range(1, sim_dict[prefix + 'NUMBER_OF_LIGHT_PROFILES'] +1): kwargs_model['lens_light_model_list'].append(sim_dict[prefix + 'LIGHT_PROFILE_{0}-NAME'.format(light_profile_num)]) #kwargs_model['lens_redshift_list'].append(sim_dict[prefix + 'REDSHIFT']) kwargs_lens_light_list.append(select_params(sim_dict, prefix + 'LIGHT_PROFILE_{0}-'.format(light_profile_num))) for mass_profile_num in range(1, sim_dict[prefix + 'NUMBER_OF_MASS_PROFILES'] +1): kwargs_model['lens_model_list'].append(sim_dict[prefix + 'MASS_PROFILE_{0}-NAME'.format(mass_profile_num)]) kwargs_model['lens_redshift_list'].append(sim_dict[prefix + 'REDSHIFT']) mass_params = select_params(sim_dict, prefix + 'MASS_PROFILE_{0}-'.format(mass_profile_num)) kwargs_lens_model_list.append(mass_params) if 'sigma_v' in mass_params.keys(): # save simga_v locations so that we can calculate theta_E for the metadata output_metadata.append({'PARAM_NAME': prefix + 'MASS_PROFILE_{0}-sigma_v-{1}'.format(mass_profile_num, band), 'PARAM_VALUE': mass_params['sigma_v'], 'LENS_MODEL_IDX': len(kwargs_lens_model_list) - 1}) for shear_profile_num in range(1, sim_dict[prefix + 'NUMBER_OF_SHEAR_PROFILES'] +1): kwargs_model['lens_model_list'].append(sim_dict[prefix + 'SHEAR_PROFILE_{0}-NAME'.format(shear_profile_num)]) kwargs_model['lens_redshift_list'].append(sim_dict[prefix + 'REDSHIFT']) mass_params = select_params(sim_dict, prefix + 'SHEAR_PROFILE_{0}-'.format(shear_profile_num)) kwargs_lens_model_list.append(select_params(sim_dict, prefix + 'SHEAR_PROFILE_{0}-'.format(shear_profile_num))) # Last Plane - treat as source elif plane_num == sim_dict['NUMBER_OF_PLANES']: kwargs_model['z_source'] = sim_dict[prefix + 'REDSHIFT'] for light_profile_num in range(1, sim_dict[prefix + 'NUMBER_OF_LIGHT_PROFILES'] +1): kwargs_model['source_light_model_list'].append(sim_dict[prefix + 'LIGHT_PROFILE_{0}-NAME'.format(light_profile_num)]) kwargs_model['source_redshift_list'].append(sim_dict[prefix + 'REDSHIFT']) kwargs_source_list.append(select_params(sim_dict, prefix + 'LIGHT_PROFILE_{0}-'.format(light_profile_num))) else: # Should never get here assert False # Make image sim = SimAPI(numpix=sim_dict['numPix'], kwargs_single_band=kwargs_single_band, kwargs_model=kwargs_model) imSim = sim.image_model_class(kwargs_numerics) kwargs_lens_light_list, kwargs_source_list, kwargs_point_source_list = sim.magnitude2amplitude(kwargs_lens_light_mag=kwargs_lens_light_list, kwargs_source_mag=kwargs_source_list, kwargs_ps_mag=kwargs_point_source_list) kwargs_lens_model_list = sim.physical2lensing_conversion(kwargs_mass=kwargs_lens_model_list) # Save theta_E (and sigma_v if used) for ii in range(len(output_metadata)): output_metadata.append({'PARAM_NAME': output_metadata[ii]['PARAM_NAME'].replace('sigma_v', 'theta_E'), 'PARAM_VALUE': kwargs_lens_model_list[output_metadata[ii]['LENS_MODEL_IDX']]['theta_E'], 'LENS_MODEL_IDX': output_metadata[ii]['LENS_MODEL_IDX']}) try: image = imSim.image(kwargs_lens=kwargs_lens_model_list, kwargs_lens_light=kwargs_lens_light_list, kwargs_source=kwargs_source_list, kwargs_ps=kwargs_point_source_list) except Exception: # Some sort of lenstronomy error print("kwargs_numerics", kwargs_numerics) print("kwargs_single_band", kwargs_single_band) print("kwargs_model", kwargs_model) print("kwargs_lens_model_list", kwargs_lens_model_list) print("kwargs_lens_light_list", kwargs_lens_light_list) print("kwargs_source_list", kwargs_source_list) print("kwargs_point_source_list", kwargs_point_source_list) assert False # Solve lens equation if desired if self.solve_lens_equation: solver = lens_equation_solver.LensEquationSolver(imSim.LensModel) x_mins, y_mins = solver.image_position_from_source(sourcePos_x=kwargs_source_list[0]['center_x'], sourcePos_y=kwargs_source_list[0]['center_y'], kwargs_lens=kwargs_lens_model_list) num_source_images = len(x_mins) # Add noise image_noise = np.zeros(np.shape(image)) for noise_source_num in range(1, sim_dict['NUMBER_OF_NOISE_SOURCES'] + 1): image_noise += self.generate_noise(sim_dict['NOISE_SOURCE_{0}-NAME'.format(noise_source_num)], np.shape(image), select_params(sim_dict, 'NOISE_SOURCE_{0}-'.format(noise_source_num))) image += image_noise # Combine with other bands output_image.append(image) # Store plane-separated info if requested if self.return_planes: output_lens.append(imSim.lens_surface_brightness(kwargs_lens_light_list)) output_source.append(imSim.source_surface_brightness(kwargs_source_list, kwargs_lens_model_list)) output_point_source.append(imSim.point_source(kwargs_point_source_list, kwargs_lens_model_list)) output_noise.append(image_noise) # Return the desired information in a dictionary return_dict = {'output_image': np.array(output_image), 'output_lens_plane': None, 'output_source_plane': None, 'output_point_source_plane': None, 'output_noise_plane': None, 'x_mins': None, 'y_mins': None, 'num_source_images': None, 'additional_metadata': output_metadata} if self.return_planes: return_dict['output_lens_plane'] = np.array(output_lens) return_dict['output_source_plane'] = np.array(output_source) return_dict['output_point_source_plane'] = np.array(output_point_source) return_dict['output_noise_plane'] = np.array(output_noise) if self.solve_lens_equation: return_dict['x_mins'] = x_mins return_dict['y_mins'] = y_mins return_dict['num_source_images'] = num_source_images return return_dict
def sim_image(self, info_dict): """ Simulate an image based on specifications in sim_dict Args: info_dict (dict): A single element from the list produced interanlly by input_reader.Organizer.breakup(). Contains all the properties of a single image to generate. """ output_image = [] if self.return_planes: output_source, output_lens, output_point_source, output_noise = [], [], [], [] output_metadata = [] #set the cosmology cosmology_info = ['H0', 'Om0', 'Tcmb0', 'Neff', 'm_nu', 'Ob0'] cosmo = FlatLambdaCDM( **dict_select_choose(list(info_dict.values())[0], cosmology_info)) for band, sim_dict in info_dict.items(): # Parse the info dict params = self.parse_single_band_info_dict(sim_dict, cosmo, band=band) kwargs_single_band = params[0] kwargs_model = params[1] kwargs_numerics = params[2] kwargs_lens_light_list = params[3] kwargs_source_list = params[4] kwargs_point_source_list = params[5] kwargs_lens_model_list = params[6] output_metadata += params[7] # Make image # data properties kwargs_data = sim_util.data_configure_simple( sim_dict['numPix'], kwargs_single_band['pixel_scale'], kwargs_single_band['exposure_time']) data_class = ImageData(**kwargs_data) # psf properties kwargs_psf = { 'psf_type': kwargs_single_band['psf_type'], 'pixel_size': kwargs_single_band['pixel_scale'], 'fwhm': kwargs_single_band['seeing'] } psf_class = PSF(**kwargs_psf) # SimAPI instance for conversion to observed quantities sim = SimAPI(numpix=sim_dict['numPix'], kwargs_single_band=kwargs_single_band, kwargs_model=kwargs_model) kwargs_lens_model_list = sim.physical2lensing_conversion( kwargs_mass=kwargs_lens_model_list) kwargs_lens_light_list, kwargs_source_list, _ = sim.magnitude2amplitude( kwargs_lens_light_mag=kwargs_lens_light_list, kwargs_source_mag=kwargs_source_list) # lens model properties lens_model_class = LensModel( lens_model_list=kwargs_model['lens_model_list'], z_lens=kwargs_model['lens_redshift_list'][0], z_source=kwargs_model['z_source'], cosmo=cosmo) # source properties source_model_class = LightModel( light_model_list=kwargs_model['source_light_model_list']) # lens light properties lens_light_model_class = LightModel( light_model_list=kwargs_model['lens_light_model_list']) # solve for PS positions to incorporate time delays lensEquationSolver = LensEquationSolver(lens_model_class) kwargs_ps = [] for ps_idx, ps_mag in enumerate(kwargs_point_source_list): # modify the SimAPI instance to do one point source at a time temp_kwargs_model = {k: v for k, v in kwargs_model.items()} temp_kwargs_model['point_source_model_list'] = [ kwargs_model['point_source_model_list'][ps_idx] ] sim = SimAPI(numpix=sim_dict['numPix'], kwargs_single_band=kwargs_single_band, kwargs_model=temp_kwargs_model) if kwargs_model['point_source_model_list'][ ps_idx] == 'SOURCE_POSITION': # convert each image to an amplitude amplitudes = [] for mag in ps_mag['magnitude']: ps_dict = {k: v for k, v in ps_mag.items()} ps_dict['magnitude'] = mag _, _2, ps = sim.magnitude2amplitude( kwargs_ps_mag=[ps_dict]) amplitudes.append(ps[0]['source_amp']) x_image, y_image = lensEquationSolver.findBrightImage( ps[0]['ra_source'], ps[0]['dec_source'], kwargs_lens_model_list, numImages=4, # max number of images min_distance=kwargs_single_band['pixel_scale'], search_window=sim_dict['numPix'] * kwargs_single_band['pixel_scale']) magnification = lens_model_class.magnification( x_image, y_image, kwargs=kwargs_lens_model_list) #amplitudes = np.array(amplitudes) * np.abs(magnification) amplitudes = np.array( [a * m for a, m in zip(amplitudes, magnification)]) kwargs_ps.append({ 'ra_image': x_image, 'dec_image': y_image, 'point_amp': amplitudes }) else: _, _2, ps = sim.magnitude2amplitude(kwargs_ps_mag=[ps_mag]) kwargs_ps.append(ps[0]) # point source properties point_source_class = PointSource(point_source_type_list=[ x if x != 'SOURCE_POSITION' else 'LENSED_POSITION' for x in kwargs_model['point_source_model_list'] ], fixed_magnification_list=[False] * len(kwargs_ps)) # create an image model image_model = ImageModel(data_class, psf_class, lens_model_class, source_model_class, lens_light_model_class, point_source_class, kwargs_numerics=kwargs_numerics) # generate image image_sim = image_model.image(kwargs_lens_model_list, kwargs_source_list, kwargs_lens_light_list, kwargs_ps) poisson = image_util.add_poisson( image_sim, exp_time=kwargs_single_band['exposure_time']) sigma_bkg = data_util.bkg_noise( kwargs_single_band['read_noise'], kwargs_single_band['exposure_time'], kwargs_single_band['sky_brightness'], kwargs_single_band['pixel_scale'], num_exposures=kwargs_single_band['num_exposures']) bkg = image_util.add_background(image_sim, sigma_bkd=sigma_bkg) image = image_sim + bkg + poisson # Save theta_E (and sigma_v if used) for ii in range(len(output_metadata)): output_metadata.append({ 'PARAM_NAME': output_metadata[ii]['PARAM_NAME'].replace( 'sigma_v', 'theta_E'), 'PARAM_VALUE': kwargs_lens_model_list[output_metadata[ii] ['LENS_MODEL_IDX']]['theta_E'], 'LENS_MODEL_IDX': output_metadata[ii]['LENS_MODEL_IDX'] }) # Solve lens equation if desired if self.solve_lens_equation: #solver = lens_equation_solver.LensEquationSolver(imSim.LensModel) #x_mins, y_mins = solver.image_position_from_source(sourcePos_x=kwargs_source_list[0]['center_x'], # sourcePos_y=kwargs_source_list[0]['center_y'], # kwargs_lens=kwargs_lens_model_list) x_mins, y_mins = x_image, y_image num_source_images = len(x_mins) # Add noise image_noise = np.zeros(np.shape(image)) for noise_source_num in range( 1, sim_dict['NUMBER_OF_NOISE_SOURCES'] + 1): image_noise += self._generate_noise( sim_dict['NOISE_SOURCE_{0}-NAME'.format(noise_source_num)], np.shape(image), select_params( sim_dict, 'NOISE_SOURCE_{0}-'.format(noise_source_num))) image += image_noise # Combine with other bands output_image.append(image) # Store plane-separated info if requested if self.return_planes: output_lens.append( image_model.lens_surface_brightness( kwargs_lens_light_list)) output_source.append( image_model.source_surface_brightness( kwargs_source_list, kwargs_lens_model_list)) output_point_source.append( image_model.point_source(kwargs_ps, kwargs_lens_model_list)) output_noise.append(image_noise) # Return the desired information in a dictionary return_dict = { 'output_image': np.array(output_image), 'output_lens_plane': None, 'output_source_plane': None, 'output_point_source_plane': None, 'output_noise_plane': None, 'x_mins': None, 'y_mins': None, 'num_source_images': None, 'additional_metadata': output_metadata } if self.return_planes: return_dict['output_lens_plane'] = np.array(output_lens) return_dict['output_source_plane'] = np.array(output_source) return_dict['output_point_source_plane'] = np.array( output_point_source) return_dict['output_noise_plane'] = np.array(output_noise) if self.solve_lens_equation: return_dict['x_mins'] = x_mins return_dict['y_mins'] = y_mins return_dict['num_source_images'] = num_source_images return return_dict