def stars(image, number, max_counts=10000, gain=1, fwhm=4): """ Add some stars to the image. """ # Most of the code below is a direct copy/paste from # https://photutils.readthedocs.io/en/stable/_modules/photutils/datasets/make.html#make_100gaussians_image flux_range = [max_counts / 10, max_counts] y_max, x_max = image.shape xmean_range = [0.1 * x_max, 0.9 * x_max] ymean_range = [0.1 * y_max, 0.9 * y_max] xstddev_range = [fwhm, fwhm] ystddev_range = [fwhm, fwhm] params = dict([('amplitude', flux_range), ('x_mean', xmean_range), ('y_mean', ymean_range), ('x_stddev', xstddev_range), ('y_stddev', ystddev_range), ('theta', [0, 2 * np.pi])]) sources = make_random_gaussians_table(number, params, seed=12345) star_im = make_gaussian_sources_image(image.shape, sources) return star_im
def genSources(): n_sources = 100 param_ranges = [('amplitude', [1000, 10000]), ('x_mean', [0, 500]), ('y_mean', [0, 300]), ('x_stddev', [3, 12]), ('y_stddev', [3, 12]), ('theta', [0, np.pi])] param_ranges = OrderedDict(param_ranges) sources = make_random_gaussians_table(n_sources, param_ranges, random_state=12345) return sources
def genStars(fwhm): stdev = fwhm / 2.355 n_sources = 100 param_ranges = [('amplitude', [1000, 35000]), ('x_mean', [0, 500]), ('y_mean', [0, 300]), ('x_stddev', [stdev - 0.1, stdev + 0.1]), ('y_stddev', [stdev - 0.1, stdev + 0.1]), ('theta', [0, np.pi])] param_ranges = OrderedDict(param_ranges) sources = make_random_gaussians_table(n_sources, param_ranges, random_state=12345) return sources
def add_fake_stars(image, expTime, number=N_STARS, max_counts=MAX_COUNTS, sky_counts=SKY_LEVEL, gain=GAIN): """ Adds fake stars to a dark image from the CCD. Used for testing while not on-telescope Input: - image The numpy array from the CCD. - number The number of stars to add - max_counts The max counts for the stars to have - sky_counts Counts to use for adding sky background - gain CCD gain - expTime The exposure time of the raw image, to scale star brightness Output: - fakeData A numpy array containing the fake star image """ # create sky background sky_im = np.random.poisson(sky_counts * gain, size=image.shape) / gain #flux_range = [max_counts/10, max_counts] # this the range for brightness, flux or counts flux_range = [ float(expTime) * (max_counts / 10), float(expTime) * (max_counts / 1) ] y_max, x_max = image.shape xmean_range = [0.1 * x_max, 0.9 * x_max] # this is where on the chip they land ymean_range = [0.1 * y_max, 0.9 * y_max] xstddev_range = [ 4, 4 ] # this is a proxy for gaussian width, FWHM, or focus I think. ystddev_range = [4, 4] params = dict([('amplitude', flux_range), ('x_mean', xmean_range), ('y_mean', ymean_range), ('x_stddev', xstddev_range), ('y_stddev', ystddev_range), ('theta', [0, 2 * np.pi])]) randInt = random.randint(11111, 99999) sources = make_random_gaussians_table(number, params, random_state=randInt) star_im = make_gaussian_sources_image(image.shape, sources) fakeData = image + sky_im + star_im return fakeData
def test_detection(StarFinder_Algorithm, sigma_psf, amplitude, PSF_size=1): '''create an image with mock sources and try to detect them Parameters ---------- StarFinder_Algorithm: Class to detect stars sigma_psf: standard deviation of the PSF of the mock sources amplitude: amplitude of the mock sources PSF_size: The StarFinder_Algorithm need to know the sigma of the sources they try to detect. This parameter changes the provided size compared to the sigma of the mock sources. ''' # create mock data n_sources = 20 tshape = (256, 256) param_ranges = OrderedDict([('amplitude', [amplitude, amplitude * 1.2]), ('x_mean', [0, tshape[0]]), ('y_mean', [0, tshape[1]]), ('x_stddev', [sigma_psf, sigma_psf]), ('y_stddev', [sigma_psf, sigma_psf]), ('theta', [0, 0])]) sources = make_random_gaussians_table(n_sources, param_ranges, random_state=1234) image = (make_gaussian_sources_image(tshape, sources) + make_noise_image( tshape, type='poisson', mean=6., random_state=1) + make_noise_image( tshape, type='gaussian', mean=0., stddev=2., random_state=34234)) fwhm = gaussian_sigma_to_fwhm * sigma_psf mean, median, std = sigma_clipped_stats(image, sigma=3.0) StarFinder = StarFinder_Algorithm(fwhm=fwhm * PSF_size, threshold=3. * std, sharplo=0.1, sharphi=1.0, roundlo=-.2, roundhi=.2) sources_mock = StarFinder(image) # for consistent table output for col in sources_mock.colnames: sources_mock[col].info.format = '%.8g' string = str(StarFinder_Algorithm).split( '.')[-1][:-2] + f' sig={sigma_psf} A={amplitude}' print(f'{string}: {len(sources_mock):} of {n_sources} sources found') positions = np.transpose( [sources_mock['xcentroid'], sources_mock['ycentroid']]) apertures = CircularAperture(positions, r=fwhm) return image, apertures, sources, string