def test_mask_saturated_pixels(): """Function to test the masking of saturated pixels in a FITS image.""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_sky_background') test_image_file = os.path.join( cwd, 'data', 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') hdulist = fits.open(test_image_file) saturation_value = hdulist[0].header['SATURATE'] image = hdulist[0].data masked_image = sky_background.mask_saturated_pixels( setup, image, saturation_value, log) fig = plt.figure(4) plt.imshow(masked_image, origin='lower', cmap=plt.cm.viridis) plt.title('Masked image') plt.savefig(os.path.join(cwd, 'data', 'masked_image_test.png')) plt.close(4) assert (os.path.isfile(os.path.join(cwd, 'data', 'masked_image_test.png'))) logs.close_log(log)
def test_reference_astrometry(): setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DATA}) log = logs.start_stage_log( cwd, 'test_wcs' ) image_path = path.join(TEST_DATA,'lsc1m005-fl15-20170701-0144-e91_cropped.fits') detected_sources_file = path.join(TEST_DATA,'lsc1m005-fl15-20170701-0144-e91_cropped_sources.txt') outputs = ['reference_detected_sources_pixels.png', 'reference_detected_sources_world.png', 'astrometry_separations.png', 'star_catalog.fits'] for item in outputs: if path.isfile(path.join(TEST_DATA,item)): remove(path.join(TEST_DATA,item)) detected_sources = catalog_utils.read_source_catalog(detected_sources_file) ref_source_catalog = wcs.reference_astrometry(setup,log,image_path,detected_sources) assert path.isfile(path.join(TEST_DATA,'ref','reference_detected_sources_pixels.png')) == True assert path.isfile(path.join(TEST_DATA,'ref','reference_detected_sources_world.png')) == True assert path.isfile(path.join(TEST_DATA,'ref','astrometry_separations.png')) == True assert path.isfile(path.join(TEST_DATA,'ref','star_catalog.fits')) == True assert path.isfile(path.join(TEST_DATA,'ref','ref_image_wcs.fits')) == True logs.close_log(log)
def test_model_sky_background(): """Function to test the function to model the sky background of an image""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_psf_selection') detected_sources_file = path.join( TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped_sources.txt') detected_sources = catalog_utils.read_source_catalog(detected_sources_file) ref_star_catalog = np.zeros([len(detected_sources), 13]) ref_star_catalog[:, 0] = detected_sources[:, 0] ref_star_catalog[:, 1] = detected_sources[:, 1] ref_star_catalog[:, 2] = detected_sources[:, 2] reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') reduction_metadata.ref_image_path = path.join( TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') log.info('Read metadata') sky_background.model_sky_background(setup, reduction_metadata, log, ref_star_catalog) logs.close_log(log)
def test_merge_catalog(): """Function to test the catalogue cross-matching function for the survey catalog builder. Based on code by Y. Tsapras. """ log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') catalog1 = survey_catalog.read_star_catalog(TEST_DIR, log) nrows = len(catalog1) row = [ 999, 999.99999, 999.999999, 99.99999, 9.99999, 99.9999, 99.999, 99.9999, 99.9999, 99.9999, 99.999, 99.9999, 99.9999, 99.9999, 99.999, 99.9999 ] catalog1.add_row(row) catalog2 = survey_catalog.read_star_catalog(TEST_DIR, log) new_stars = range(0, len(catalog2), 1) star_catalog = survey_catalog.add_new_stars_to_catalog( new_stars, catalog2, None, log) star_catalog = survey_catalog.merge_catalogs(catalog1, star_catalog, log) assert len(star_catalog) == nrows + 1 logs.close_log(log)
def build_survey_catalog(): """Function to build a single catalogue including all stars detected in the ROME/REA survey. """ params = get_args() log = logs.start_stage_log(params['log_dir'], 'survey_catalog', version=VERSION) params = list_reduced_datasets(params, log) star_catalog = read_existing_survey_catalog(params, log) for red_dir in params['datasets']: catalog = read_star_catalog(red_dir, log) star_catalog = merge_catalogs(catalog, star_catalog, log) catalog_file = os.path.join(params['log_dir'], 'survey_star_catalog.fits') catalog_utils.output_survey_catalog(catalog_file, star_catalog, log) log.info('Survey catalogue construction complete.') logs.close_log(log)
def test_id_crowded_stars(): """Function to test the exclusion of crowded stars from the PSF star selection process""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log( cwd, 'test_psf_selection' ) reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') log.info('Read metadata') nstars = 10 bright = 16.0 faint = 23.0 ref_star_catalog = np.zeros([nstars,13]) ref_star_catalog[:,0] = range(0,nstars,1) istar = -1 for j in range(0,7,1): istar += 1 ref_star_catalog[istar,1] = abs(random.normalvariate(100.0,100.0)) ref_star_catalog[istar,2] = abs(random.normalvariate(100.0,100.0)) ref_star_catalog[istar,5] = abs(random.normalvariate(16.0,0.5)) exclude = [] for j in range(istar,nstars,1): i = random.randint(0,2) xstar = ref_star_catalog[i,1] ystar = ref_star_catalog[i,2] ref_star_catalog[j,1] = random.normalvariate(xstar,1.0) ref_star_catalog[j,2] = random.normalvariate(ystar,1.0) ref_star_catalog[j,5] = abs(random.normalvariate(17.0,0.5)) exclude.append(i) ref_star_catalog[:,3] = random.normalvariate(17.0*15.0,20.0) ref_star_catalog[:,4] = random.normalvariate(-27.0,10.0) ref_star_catalog[:,6] = 0.005 + ref_star_catalog[:,4]*0.05 psf_stars_idx = np.array([1]*nstars) psf_stars_idx = psf_selection.id_crowded_stars(setup,reduction_metadata,log, ref_star_catalog,psf_stars_idx) psf_selection.plot_ref_star_catalog_positions(setup,reduction_metadata,log, ref_star_catalog, psf_stars_idx) star_index = np.where(psf_stars_idx == 1)[0] for j in exclude: assert j not in star_index logs.close_log(log)
def test_read_star_catalog(): """Function to test the read of a star catalog from a reduction's metadata file""" log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') catalog = survey_catalog.read_star_catalog(TEST_DIR, log) t = Table(np.zeros(5)) assert type(catalog) == type(t) logs.close_log(log)
def test_id_mid_range_stars(): """Function to test the selection of stars in the reference image, excluding the brightest and faintest N% of those detected""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log( cwd, 'test_psf_selection' ) reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') log.info('Read metadata') # Generating test catalog with columns: # idx x y ra dec inst_mag inst_mag_err J Jerr H Herr K Kerr nstars = 10 bright = 16.0 faint = 23.0 ref_star_catalog = np.zeros([nstars,13]) ref_star_catalog[:,0] = range(0,nstars,1) ref_star_catalog[:,1] = random.normalvariate(100.0,100.0) ref_star_catalog[:,2] = random.normalvariate(100.0,100.0) ref_star_catalog[:,3] = random.normalvariate(17.0*15.0,20.0) ref_star_catalog[:,4] = random.normalvariate(-27.0,10.0) ref_star_catalog[:,5] = np.arange(bright,faint,(faint-bright)/float(nstars)) ref_star_catalog[:,6] = 0.005 + ref_star_catalog[:,4]*0.05 psf_stars_idx = np.array([1]*nstars) psf_range_thresh = reduction_metadata.reduction_parameters[1]['PSF_RANGE_THRESH'][0] log.info('Read psf range threshold = '+str(psf_range_thresh)) nstar_cut = int(float(nstars) * (psf_range_thresh/100.0)) istart = nstar_cut iend = len(ref_star_catalog) - nstar_cut test_psf_stars_idx = np.ones(nstars) test_psf_stars_idx[0:nstar_cut] = 0 test_psf_stars_idx[(-1*nstar_cut):] = 0 psf_stars_idx = psf_selection.id_mid_range_stars(setup,reduction_metadata, log, ref_star_catalog, psf_stars_idx) assert psf_stars_idx.all() == test_psf_stars_idx.all() logs.close_log(log)
def test_create_survey_catalog(): """Function to test the creation of a survey catalog Table object""" log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') star_catalog = survey_catalog.create_survey_catalog(log, 10) test_table = Table() assert type(star_catalog) == type(test_table) assert 'ID' in star_catalog.colnames assert 'RA_J2000' in star_catalog.colnames assert 'DEC_J2000' in star_catalog.colnames assert 'Blend' in star_catalog.colnames logs.close_log(log)
def test_trigger_reduction(): """Function to test the spawning of reduction processes""" setup = pipeline_setup.pipeline_setup(params) log = logs.start_pipeline_log(setup.log_dir, 'test_pipeline_control', version=VERSION) dataset_dir = TEST_DATA pid = pipeline_control.trigger_reduction(setup, dataset_dir, debug=True) assert type(pid) == type(1) logs.close_log(log)
def test_get_datasets(): """Function to test the function which identifies which datasets should be reduced. """ setup = pipeline_setup.pipeline_setup(params) log = logs.start_pipeline_log(setup.log_dir, 'test_pipeline_control', version=VERSION) datasets = pipeline_control.get_datasets_for_reduction(setup, log) assert type(datasets) == type(['a', 'b', 'c']) logs.close_log(log)
def test_list_reducted_datasets(): """Function to test the gathering of datasets to be combined into a single survey catalogue.""" log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') params = {'data_dir': os.path.join(TEST_DIR, '..')} params = survey_catalog.list_reduced_datasets(params, log) t_list = [os.path.join(TEST_DIR, '..', os.path.basename(TEST_DIR))] assert 'datasets' in params.keys() assert params['datasets'] == t_list logs.close_log(log)
def test_build_psf(): setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_build_psf') log.info(setup.summary()) reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') reduction_metadata.reference_image_path = os.path.join( TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') reduction_metadata.background_type = 'constant' star_catalog_file = os.path.join(TEST_DATA, 'star_catalog.fits') ref_star_catalog = catalog_utils.read_ref_star_catalog_file( star_catalog_file) log.info('Read in catalog of ' + str(len(ref_star_catalog)) + ' stars') psf_stars_idx = np.zeros(len(ref_star_catalog)) psf_stars_idx[400:500] = 1 ref_star_catalog[:, 13] = psf_stars_idx ref_image = fits.getdata(reduction_metadata.reference_image_path) log.info('Loaded reference image') sky_model = psf.ConstantBackground() sky_model.constant = 1345.0 sky_model.background_parameters.constant = 1345.0 (psf_model, status) = psf.build_psf(setup, reduction_metadata, log, ref_image, ref_star_catalog, sky_model, diagnostics=True) logs.close_log(log)
def pipeline_control(): """Main driver program controlling the reduction of multiple datasets with pyDANDIA. """ pipeline_version = 'pipeline_control v0.1' setup = get_pipeline_setup() log = logs.start_pipeline_log(setup.log_dir, 'pipeline_control', version=pipeline_version) datasets = get_datasets_for_reduction(setup, log) run_reductions(setup, log, datasets) logs.close_log(log)
def test_stage_log(): """Function to test the initialization and closing of a stage log""" log = logs.start_stage_log( cwd, 'test_log' ) chk_log = logging.getLogger( 'test' ) log_name = path.join(cwd,'test_log.log') assert type(log) == type(chk_log) assert path.isfile(log_name) logs.close_log(log) file_lines = open(log_name,'r').readlines() assert len(file_lines) > 0 assert 'Processing complete' in file_lines[-2]
def test_xmatch_catalog(): """Function to test the catalogue cross-matching function for the survey catalog builder. Based on code by Y. Tsapras. """ log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') catalog1 = survey_catalog.read_star_catalog(TEST_DIR, log) catalog2 = survey_catalog.read_star_catalog(TEST_DIR, log) (matched_table, blends) = survey_catalog.xmatch_catalogs(catalog1, catalog2, log) assert len(matched_table[0]) > int(len(catalog1) * 0.9) assert len(blends) > 0 logs.close_log(log)
def reduction_control(): """Main driver function for the pyDANDIA pipelined reduction of an individual dataset. A single dataset is defined as a set of images taken with a consistent instrument configuration and filter of a single sky pointing. Input parameters: dataset_red_dir str Full path to the reduction directory for this dataset """ reduction_version = 'reduction_control v0.2' setup = get_args() log = logs.start_pipeline_log(setup.red_dir, 'reduction_control', version=reduction_version) (status, report, meta_data) = stage0.run_stage0(setup) log.info('Completed stage 0 with status ' + repr(status) + ': ' + report) (status, report) = stage1.run_stage1(setup) log.info('Completed stage 1 with status ' + repr(status) + ': ' + report) (status, report) = stage2.run_stage2(setup) log.info('Completed stage 2 with status ' + repr(status) + ': ' + report) (status, report) = stage3.run_stage3(setup) log.info('Completed stage 3 with status ' + repr(status) + ': ' + report) (status, report) = stage4.run_stage4(setup) log.info('Completed stage 4 with status ' + repr(status) + ': ' + report) (status, report) = stage5.run_stage5(setup) log.info('Completed stage 5 with status ' + repr(status) + ': ' + report) (status, report) = stage6.run_stage6(setup) log.info('Completed stage 6 with status ' + repr(status) + ': ' + report) logs.close_log(log)
def test_model_sky_background(): """Function to test the fitting of a sky background model to a masked real star image.""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_sky_background') reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'images_stats') log.info('Read metadata') # Need to check where these parameters come from reduction_metadata.reference_image_path = os.path.join( cwd, 'data', 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') reduction_metadata.background_type = 'constant' ref_star_catalog_file = os.path.join(cwd, 'data', 'star_catalog.fits') ref_star_catalog = catalog_utils.read_ref_star_catalog_file( ref_star_catalog_file) log.info('Read reference image star catalog from ' + ref_star_catalog_file) sky_model = sky_background.model_sky_background(setup, reduction_metadata, log, ref_star_catalog) log.info('Fit image sky background with '+\ reduction_metadata.background_type+' model, parameters:') for key in sky_model.model: log.info(key + ' = ' + str(getattr(sky_model.background_parameters, key))) logs.close_log(log)
def test_fit_psf_model(): """Function to test the ability to fit a PSF model to a given stamp image, optimizing all parameters """ setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_fit_psf_model') log.info(setup.summary()) psf_model_type = 'Moffat2D' sky_model_type = 'Constant' image_file = os.path.join(TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') image = fits.getdata(image_file) stamp_centres = np.array([[194.654006958, 180.184967041]]) stamp_dims = (20, 20) stamps = psf.cut_image_stamps(setup, image, stamp_centres, stamp_dims) fitted_psf = psf.fit_psf_model(setup, log, psf_model_type, sky_model_type, stamps[0], diagnostics=True) assert type(fitted_psf) == type(psf.Moffat2D()) log.info('Parameters of fitted PSF model:') for key in fitted_psf.model: log.info(key + ' = ' + str(getattr(fitted_psf.psf_parameters, key))) logs.close_log(log)
def test_run_iterative_PSF_photometry(): """Function to test the PSF-fitting photometry module for a single image""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_photometry') reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'images_stats') log.info('Read metadata') # NOTE: Once stage 2 is complete, the reference image path should be # extracted directly from the metadata. reduction_metadata.reference_image_path = os.path.join( TEST_DIR, 'data', 'lsc1m005-fl15-20170418-0131-e91_cropped.fits') image_path = reduction_metadata.reference_image_path log.info('Performing PSF fitting photometry on ' + os.path.basename(image_path)) phot_data = photometry.run_iterative_PSF_photometry(setup, reduction_metadata, image_path, log, diagnostics=True) test_output = Table() assert type(phot_data) == type(test_output) logs.close_log(log)
def test_add_new_stars_to_catalog(): """Function to test the addition of new stars to an existing master catalogue.""" log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') params = { 'old_star_catalog': os.path.join(TEST_DIR, '..', 'survey_star_catalog.fits') } star_catalog = survey_catalog.read_existing_survey_catalog(params, log) nrows = len(star_catalog) new_catalog = survey_catalog.read_star_catalog(TEST_DIR, log) new_stars = set([1, 2, 3]) star_catalog = survey_catalog.add_new_stars_to_catalog( new_stars, new_catalog, star_catalog, log) assert len(star_catalog) == nrows + 3 logs.close_log(log)
def test_read_existing_survey_catalog(): """Function to test the reading of a previously-existing star catalog""" log = logs.start_stage_log(LOG_DIR, 'test_survey_catalog') params = {'old_star_catalog': 'NONE'} star_catalog = survey_catalog.read_existing_survey_catalog(params, log) assert star_catalog == None params = { 'old_star_catalog': os.path.join(TEST_DIR, '..', 'survey_star_catalog.fits') } star_catalog = survey_catalog.read_existing_survey_catalog(params, log) test_table = Table() assert type(star_catalog) == type(test_table) assert len(star_catalog) > 0 logs.close_log(log)
def test_subtract_companions_from_psf_stamps(): """Function to test the function which removes companion stars from the surrounds of a PSF star in a PSF star stamp image.""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_subtract_companions') log.info(setup.summary()) reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') star_catalog_file = os.path.join(TEST_DATA, 'star_catalog.fits') ref_star_catalog = catalog_utils.read_ref_star_catalog_file( star_catalog_file) log.info('Read in catalog of ' + str(len(ref_star_catalog)) + ' stars') image_file = os.path.join(TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') image = fits.getdata(image_file) psf_idx = [248] psf_x = 257.656 psf_y = 121.365 stamp_centres = np.array([[psf_x, psf_y]]) psf_size = 10.0 stamp_dims = (20, 20) stamps = psf.cut_image_stamps(setup, image, stamp_centres, stamp_dims) if len(stamps) == 0: log.info( 'ERROR: No PSF stamp images returned. PSF stars too close to the edge?' ) else: for i, s in enumerate(stamps): fig = plt.figure(1) norm = visualization.ImageNormalize(s.data, \ interval=visualization.ZScaleInterval()) plt.imshow(s.data, origin='lower', cmap=plt.cm.viridis, norm=norm) plt.xlabel('X pixel') plt.ylabel('Y pixel') plt.axis('equal') plt.savefig( os.path.join(setup.red_dir, 'psf_star_stamp' + str(i) + '.png')) plt.close(1) psf_model = psf.Moffat2D() x_cen = psf_size + (psf_x - int(psf_x)) y_cen = psf_size + (psf_x - int(psf_y)) psf_radius = 8.0 psf_params = [ 103301.241291, x_cen, y_cen, 226.750731765, 13004.8930993, 103323.763627 ] psf_model.update_psf_parameters(psf_params) sky_model = psf.ConstantBackground() sky_model.background_parameters.constant = 1345.0 clean_stamps = psf.subtract_companions_from_psf_stamps( setup, reduction_metadata, log, ref_star_catalog, psf_idx, stamps, stamp_centres, psf_model, sky_model, diagnostics=True) logs.close_log(log)
def test_run_psf_photometry(): """Function to test the PSF-fitting photometry module for a single image""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_photometry') reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'images_stats') log.info('Read metadata') # NOTE: Once stage 2 is complete, the reference image path should be # extracted directly from the metadata. reduction_metadata.reference_image_path = os.path.join( TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') image_path = reduction_metadata.reference_image_path star_catalog_file = os.path.join(TEST_DATA, 'star_catalog.fits') ref_star_catalog = catalog_utils.read_ref_star_catalog_file( star_catalog_file) psf_model = psf.get_psf_object('Moffat2D') xstar = 194.654006958 ystar = 180.184967041 psf_size = 8.0 x_cen = psf_size + (xstar - int(xstar)) y_cen = psf_size + (ystar - int(ystar)) psf_params = [5807.59961215, x_cen, y_cen, 7.02930822229, 11.4997891585] psf_model.update_psf_parameters(psf_params) sky_model = psf.ConstantBackground() sky_model.background_parameters.constant = 1345.0 log.info('Performing PSF fitting photometry on ' + os.path.basename(image_path)) ref_star_catalog = photometry.run_psf_photometry(setup, reduction_metadata, log, ref_star_catalog, image_path, psf_model, sky_model, centroiding=True) assert ref_star_catalog[:, 5].max() > 0.0 assert ref_star_catalog[:, 6].max() > 0.0 assert ref_star_catalog[:, 5].max() <= 25.0 assert ref_star_catalog[:, 6].max() <= 10.0 logs.close_log(log)
def test_find_psf_companion_stars(): """Function to test the identification of stars that neighbour a PSF star from the reference catalogue.""" setup = pipeline_setup.pipeline_setup({'red_dir': TEST_DIR}) log = logs.start_stage_log(cwd, 'test_find_psf_companions') log.info(setup.summary()) reduction_metadata = metadata.MetaData() reduction_metadata.load_a_layer_from_file(setup.red_dir, 'pyDANDIA_metadata.fits', 'reduction_parameters') star_catalog_file = os.path.join(TEST_DATA, 'star_catalog.fits') ref_star_catalog = catalog_utils.read_ref_star_catalog_file( star_catalog_file) log.info('Read in catalog of ' + str(len(ref_star_catalog)) + ' stars') psf_idx = 18 psf_x = 189.283172607 psf_y = 9.99084472656 psf_size = 8.0 stamp_dims = (20, 20) comps_list = psf.find_psf_companion_stars(setup, psf_idx, psf_x, psf_y, psf_size, ref_star_catalog, log, stamp_dims) assert len(comps_list) > 0 for l in comps_list: log.info(repr(l)) image_file = os.path.join(TEST_DATA, 'lsc1m005-fl15-20170701-0144-e91_cropped.fits') image = fits.getdata(image_file) corners = psf.calc_stamp_corners(psf_x, psf_y, stamp_dims[1], stamp_dims[0], image.shape[1], image.shape[0], over_edge=True) stamp = image[corners[2]:corners[3], corners[0]:corners[1]] log.info('Extracting PSF stamp image') fig = plt.figure(1) norm = visualization.ImageNormalize(stamp, \ interval=visualization.ZScaleInterval()) plt.imshow(stamp, origin='lower', cmap=plt.cm.viridis, norm=norm) x = [] y = [] for j in range(0, len(comps_list), 1): x.append(comps_list[j][1]) y.append(comps_list[j][2]) plt.plot(x, y, 'r+') plt.axis('equal') plt.xlabel('X pixel') plt.ylabel('Y pixel') plt.savefig(os.path.join(TEST_DATA, 'psf_companion_stars.png')) plt.close(1) logs.close_log(log)