def test_find_apertures_with_fake_data(seeing): """ Creates a fake AD object with a gaussian profile in spacial direction with a fwhm defined by the seeing variable in arcsec. Then add some noise, and test if p.findAperture can find its position. """ astrofaker = pytest.importorskip("astrofaker") gmos_fake_noise = 4 # adu gmos_plate_scale = 0.0807 # arcsec . px-1 fwhm_to_stddev = 2 * np.sqrt(2 * np.log(2)) ad = astrofaker.create('GMOS-S', mode='SPECT') ad.init_default_extensions() y0 = np.random.randint(low=100, high=ad[0].shape[0] - 100) fwhm = seeing / gmos_plate_scale stddev = fwhm / fwhm_to_stddev model = Gaussian1D(mean=y0, stddev=stddev, amplitude=50) rows, cols = np.mgrid[:ad.shape[0][0], :ad.shape[0][1]] for ext in ad: ext.data = model(rows) ext.data += np.random.poisson(ext.data) ext.data += (np.random.random(size=ext.data.shape) - 0.5) * gmos_fake_noise ext.mask = np.zeros_like(ext.data, dtype=np.uint) p = GMOSSpect([ad]) _ad = p.findSourceApertures()[0] print(_ad.info)
def test_find_apertures_with_fake_data(peak_position, peak_value, seeing, astrofaker): """ Creates a fake AD object with a gaussian profile in spacial direction with a fwhm defined by the seeing variable in arcsec. Then add some noise, and test if p.findAperture can find its position. """ np.random.seed(42) gmos_fake_noise = 4 # adu gmos_plate_scale = 0.0807 # arcsec . px-1 fwhm_to_stddev = 2 * np.sqrt(2 * np.log(2)) ad = astrofaker.create('GMOS-S', mode='SPECT') ad.init_default_extensions() fwhm = seeing / gmos_plate_scale stddev = fwhm / fwhm_to_stddev model = Gaussian1D(mean=peak_position, stddev=stddev, amplitude=peak_value) rows, cols = np.mgrid[:ad.shape[0][0], :ad.shape[0][1]] for ext in ad: ext.data = model(rows) ext.data += np.random.poisson(ext.data) ext.data += (np.random.random(size=ext.data.shape) - 0.5) * gmos_fake_noise ext.mask = np.zeros_like(ext.data, dtype=np.uint) p = GMOSSpect([ad]) _ad = p.findSourceApertures(max_apertures=1)[0] for _ext in _ad: # ToDo - Could we improve the primitive to have atol=0.50 or less? np.testing.assert_allclose(_ext.APERTURE['c0'], peak_position, atol=0.6)
def test_cosmics_on_mosaiced_data(path_to_inputs, caplog): ad = astrodata.open(os.path.join(path_to_inputs, TESFILE1)) ext = ad[0] # add some additional fake cosmics size = 50 np.random.seed(42) cr_x = np.random.randint(low=5, high=ext.shape[0] - 5, size=size) cr_y = np.random.randint(low=5, high=ext.shape[1] - 5, size=size) # Don't add cosmics in masked regions mask = binary_dilation(ext.mask > 0, iterations=3) sel = ~mask[cr_x, cr_y] cr_x = cr_x[sel] cr_y = cr_y[sel] cr_brightnesses = np.random.uniform(low=1000, high=5000, size=len(cr_x)) ext.data[cr_x, cr_y] += cr_brightnesses # Store mask of CR to help debugging crmask = np.zeros(ext.shape, dtype=np.uint8) crmask[cr_x, cr_y] = 1 ext.CRMASK = crmask debug = os.getenv('DEBUG') is not None p = GMOSSpect([ad]) adout = p.flagCosmicRays(y_order=3, bkgfit_niter=5, debug=debug)[0] if debug: p.writeOutputs() mask = adout[0].mask # check some pixels with real cosmics for pix in [(496, 519), (138, 219), (420, 633), (297, 1871)]: assert (mask[pix] & DQ.cosmic_ray) == DQ.cosmic_ray # And check our fake cosmics. assert np.all(mask[np.where(ext.CRMASK)] & DQ.cosmic_ray == DQ.cosmic_ray)
def test_find_apertures_using_standard_star(ad_and_center): """ Test that p.findApertures can find apertures in Standard Star (which are normally bright) observations. """ ad, expected_center = ad_and_center p = GMOSSpect([ad]) _ad = p.findSourceApertures(max_apertures=1).pop() assert hasattr(ad[0], 'APERTURE') assert len(ad[0].APERTURE) == 1 np.testing.assert_allclose(ad[0].APERTURE['c0'], expected_center, 3)
def create_inputs_recipe(): """ Creates input data for tests using pre-processed standard star and its calibration files. The raw files will be downloaded and saved inside the path stored in the `$DRAGONS_TEST/raw_inputs` directory. Processed files will be stored inside a new folder called "dragons_test_inputs". The sub-directory structure should reflect the one returned by the `path_to_inputs` fixture. """ import os from astrodata.testing import download_from_archive from geminidr.gmos.tests.spect import CREATED_INPUTS_PATH_FOR_TESTS from gempy.utils import logutils from recipe_system.reduction.coreReduce import Reduce module_name, _ = os.path.splitext(os.path.basename(__file__)) path = os.path.join(CREATED_INPUTS_PATH_FOR_TESTS, module_name) os.makedirs(path, exist_ok=True) os.chdir(path) os.makedirs("inputs", exist_ok=True) cwd = os.getcwd() associated_arcs = { "N20180109S0287.fits": "N20180109S0315.fits", # GN-2017B-FT-20-13-001 B600 0.505um "N20190302S0089.fits": "N20190302S0274.fits", # GN-2019A-Q-203-7-001 B600 0.550um "N20190313S0114.fits": "N20190313S0132.fits", # GN-2019A-Q-325-13-001 B600 0.482um "N20190427S0126.fits": "N20190427S0267.fits", # GN-2019A-FT-206-7-004 R400 0.625um "N20190910S0028.fits": "N20190910S0279.fits", # GN-2019B-Q-313-5-001 B600 0.550um "S20180919S0139.fits": "S20180919S0141.fits", # GS-2018B-Q-209-13-003 B600 0.45um "S20191005S0051.fits": "S20191005S0147.fits", # GS-2019B-Q-132-35-001 R400 0.73um } for sci_fname, arc_fname in associated_arcs.items(): sci_path = download_from_archive(sci_fname) arc_path = download_from_archive(arc_fname) sci_ad = astrodata.open(sci_path) data_label = sci_ad.data_label() logutils.config(file_name='log_arc_{}.txt'.format(data_label)) arc_reduce = Reduce() arc_reduce.files.extend([arc_path]) # arc_reduce.ucals = normalize_ucals(arc_reduce.files, calibration_files) os.chdir("inputs/") arc_reduce.runr() arc_ad = arc_reduce.output_filenames.pop() logutils.config(file_name='log_{}.txt'.format(data_label)) p = GMOSSpect([sci_ad]) p.prepare() p.addDQ(static_bpm=None) p.addVAR(read_noise=True) p.overscanCorrect() p.ADUToElectrons() p.addVAR(poisson_noise=True) p.distortionCorrect(arc=arc_ad) p.writeOutputs() os.chdir("../") os.chdir(cwd)
def create_inputs_recipe(): """ Creates input data for tests using pre-processed standard star and its calibration files. The raw files will be downloaded and saved inside the path stored in the `$DRAGONS_TEST/raw_inputs` directory. Processed files will be stored inside a new folder called "dragons_test_inputs". The sub-directory structure should reflect the one returned by the `path_to_inputs` fixture. """ fnames = ["S20190808S0048.fits"] path = pathlib.Path('dragons_test_inputs') path = path / "geminidr" / "gmos" / "spect" / "test_cosmics" / "inputs" path.mkdir(exist_ok=True, parents=True) os.chdir(path) print('Current working directory:\n {!s}'.format(path.cwd())) for fname in fnames: sci_ad = astrodata.open(download_from_archive(fname)) data_label = sci_ad.data_label() print('===== Reducing pre-processed data =====') logutils.config(file_name=f'log_{data_label}.txt') p = GMOSSpect([sci_ad]) p.prepare() p.addDQ(static_bpm=None) p.addVAR(read_noise=True) p.overscanCorrect() p.ADUToElectrons() p.addVAR(poisson_noise=True) p.writeOutputs() p.mosaicDetectors() p.writeOutputs()