Example #1
0
def test_mosaic_detectors_gmos_binning(astrofaker, hemi, ccd):
    """
    Tests that the spacing between amplifier centres for NxN binned data
    is precisely N times smaller than for unbinned data when run through
    mosaicDetectors()
    """
    for binning in (1, 2, 4):
        try:
            ad = astrofaker.create('GMOS-{}'.format(hemi), ['IMAGE', ccd])
        except ValueError:  # No e2v for GMOS-S
            pytest.skip()

        ad.init_default_extensions(binning=binning, overscan=False)
        for ext in ad:
            shape = ext.data.shape
            ext.add_star(amplitude=10000,
                         x=0.5 * (shape[1] - 1),
                         y=0.5 * (shape[0] - 1),
                         fwhm=0.5 * binning)
        p = GMOSImage([ad])
        ad = p.mosaicDetectors([ad])[0]
        ad = p.detectSources([ad])[0]
        x = np.array(sorted(ad[0].OBJCAT['X_IMAGE']))
        if binning == 1:
            unbinned_positions = x
        else:
            diffs = np.diff(unbinned_positions) - binning * np.diff(x)
            assert np.max(abs(diffs)) < 0.01
Example #2
0
    def test_measureBG(self, ad):

        p = GMOSImage([ad])
        ad = p.measureBG()[0]

        correct = [
            726.18213, 724.36047, 727.34491, 728.49664, 728.08966, 719.83728
        ]

        for rv, cv in zip(ad.hdr['SKYLEVEL'], correct):
            assert abs(rv - cv) < 0.1, 'Wrong background level'

        assert (ad.phu['SKYLEVEL'] - 727.174) < 0.1

        f = open(logfilename)

        for line in f.readlines():
            if 'BG band' in line:
                assert line.split()[6] == 'BG80', 'Wrong BG band'

        ad.phu['REQBG'] = '50-percentile'
        ad = p.measureBG()[0]

        assert any('WARNING: BG requirement not met' in line
                   for line in f.readlines()), 'No BG warning'
Example #3
0
    def test_measureIQ(self):
        ad = astrodata.open(
            os.path.join(TESTDATAPATH, 'GMOS',
                         'N20150624S0106_refcatAdded.fits'))
        p = GMOSImage([ad])
        ad = p.measureIQ()[0]
        # Try to give a reasonable-sized goal
        assert abs(ad.phu['MEANFWHM'] - 0.42) < 0.02, 'Wrong FWHM'
        assert abs(ad.phu['MEANELLP'] - 0.09) < 0.02, 'Wrong ellipticity'

        f = open(logfilename, 'r')
        for line in f.readlines():
            if 'IQ range' in line:
                assert line.split()[8] == 'IQ20', 'Wrong IQ band'

        ad.phu['REQIQ'] = '70-percentile'
        for ext in ad:
            ext.OBJCAT['PROFILE_FWHM'] *= 2.5
            ext.OBJCAT['PROFILE_EE50'] *= 2.5
        ad = p.measureIQ()[0]
        iqwarn = False
        for line in f.readlines():
            if 'IQ range' in line:
                assert line.split()[8] == 'IQ85', 'Wrong IQ band after edit'
            iqwarn |= 'WARNING: IQ requirement not met' in line
        assert iqwarn, 'NO IQ warning'
Example #4
0
def plot(ad):
    """
    Displays the tiled arrays with the DQ mask for analysing the data.

    Parameters
    ----------
    ad : multi-extension data
    """
    from astropy.visualization import ImageNormalize, ZScaleInterval
    from copy import deepcopy
    import numpy as np
    import matplotlib.pyplot as plt

    p = GMOSImage([deepcopy(ad)])
    _ad = p.tileArrays().pop()

    fig, axs = plt.subplots(num=ad.filename, ncols=len(_ad), sharey=True)

    norm = ImageNormalize(
        np.concatenate([ext.data.ravel()[ext.mask.ravel() == 0] for ext in _ad]),
        interval=ZScaleInterval())

    vmin = norm.vmin
    vmax = norm.vmax

    for i, ext in enumerate(_ad):

        data = np.ma.masked_array(ext.data, mask=ext.mask)
        cmap = plt.get_cmap('viridis')
        cmap.set_bad('red', alpha='0.5')
        axs[i].imshow(data, origin='lower', cmap=cmap, vmin=vmin, vmax=vmax)
        # axs[i].imshow(data.data, origin='lower', vmin=vmin, vmax=vmax)

    plt.show()
Example #5
0
    def test_measureCC(self):
        ad = astrodata.open(
            os.path.join(TESTDATAPATH, 'GMOS',
                         'N20150624S0106_refcatAdded.fits'))
        p = GMOSImage([ad])
        ad = p.measureCC()[0]
        correct = [28.18, 28.16, 28.14, 28.11, 28.17, 28.12]
        for rv, cv in zip(ad.hdr['MEANZP'], correct):
            assert abs(rv - cv) < 0.02, 'Wrong zeropoint'

        f = open(logfilename, 'r')
        for line in f.readlines():
            if 'CC bands' in line:
                assert 'CC50, CC70' in line, 'Wrong CC bands'
        for ext in ad:
            ext.OBJCAT['MAG_AUTO'] += 0.3
        ad = p.measureCC()[0]
        correct = [c - 0.3 for c in correct]
        for rv, cv in zip(ad.hdr['MEANZP'], correct):
            assert abs(rv - cv) < 0.02, 'Wrong zeropoint after edit'
        ccwarn = False
        for line in f.readlines():
            if 'CC bands' in line:
                assert 'CC70, CC80' in line, 'Wrong CC bands after edit'
            ccwarn |= 'WARNING: CC requirement not met' in line
        assert ccwarn, 'No CC warning'
Example #6
0
    def test_measureIQ(self, ad):

        p = GMOSImage([ad])
        ad = p.measureIQ()[0]
        # Try to give a reasonable-sized goal
        assert abs(ad.phu['MEANFWHM'] - 0.42) < 0.02, 'Wrong FWHM'
        assert abs(ad.phu['MEANELLP'] - 0.09) < 0.02, 'Wrong ellipticity'

        f = open(logfilename)
        for line in f.readlines():
            if 'IQ range' in line:
                assert line.split()[8] == 'IQ20', 'Wrong IQ band'

        ad.phu['REQIQ'] = '70-percentile'
        for ext in ad:
            ext.OBJCAT['PROFILE_FWHM'] *= 2.5
            ext.OBJCAT['PROFILE_EE50'] *= 2.5

        ad = p.measureIQ()[0]
        iqwarn = False

        for line in f.readlines():
            if 'IQ range' in line:
                assert line.split()[8] == 'IQ85', 'Wrong IQ band after edit'
            iqwarn |= 'WARNING: IQ requirement not met' in line

        assert iqwarn, 'NO IQ warning'
Example #7
0
def test_add_object_mask_to_dq(astrofaker):
    ad_orig = astrofaker.create('F2', 'IMAGE')

    # astrodata.open(os.path.join(TESTDATAPATH, 'GMOS', 'N20150624S0106_refcatAdded.fits'))
    p = GMOSImage([deepcopy(ad_orig)])
    ad = p.addObjectMaskToDQ()[0]

    for ext, ext_orig in zip(ad, ad_orig):
        assert all(
            ext.mask[ext.OBJMASK == 0] == ext_orig.mask[ext.OBJMASK == 0])
        assert all(
            ext.mask[ext.OBJMASK == 1] == ext_orig.mask[ext.OBJMASK == 1] | 1)
Example #8
0
def test_add_oiwfs_runs_normally(caplog, ext_num, filename, x0, y0):
    """
    Test that the primitive does not run if the input file does not have a DQ
    plan.

    Parameters
    ----------
    caplog : fixture
    filename : str
    """
    caplog.set_level(logging.DEBUG)
    file_path = download_from_archive(filename)
    ad = astrodata.open(file_path)

    p = GMOSImage([ad])
    p.addDQ()
    p.addVAR(read_noise=True)
    p.addOIWFSToDQ()

    # plot(p.streams['main'][0])
    assert len(caplog.records) > 0
    assert any("Guide star location found at" in r.message for r in caplog.records)

    # Some kind of regression test
    for r in caplog.records:
        if r.message.startswith("Guide star location found at"):
            coords = re.findall(r"\((.*?)\)", r.message).pop().split(',')

            x = float(coords[0])
            y = float(coords[1])
            n = int(r.message.split(' ')[-1])

            assert abs(x - x0) < 1
            assert abs(y - y0) < 1
            assert n == ext_num
Example #9
0
def test_add_oiwfs_warns_when_wfs_if_not_in_field(caplog, filename):
    """
    Test that the primitive does not run if the input file does not have a DQ
    plan.

    Parameters
    ----------
    caplog : fixture
    filename : str
    """
    caplog.set_level(logging.DEBUG)
    file_path = download_from_archive(filename)
    ad = astrodata.open(file_path)

    p = GMOSImage([ad])
    p.addDQ()
    p.addVAR(read_noise=True)
    p.addOIWFSToDQ()

    # plot(p.streams['main'][0])
    print(caplog.records)
    assert any("No good rows in" in r.message for r in caplog.records)

    assert any("Cannot distinguish probe region from sky for"
               in r.message for r in caplog.records)
Example #10
0
def test_gmos_wcs_stability(raw_ad_path, do_prepare, do_overscan_correct,
                            tile_all):
    raw_ad = astrodata.open(raw_ad_path)

    # Ensure it's tagged IMAGE so we can get an imaging WCS and can use SkyCoord
    raw_ad.phu['GRATING'] = 'MIRROR'

    # Check the reference extension is what we think and find the middle
    ref_index = find_reference_extension(raw_ad)
    assert ref_index == (len(raw_ad) - 1) // 2  # works for GMOS
    y, x = [length // 2 for length in raw_ad[ref_index].shape]
    c0 = SkyCoord(*raw_ad[ref_index].wcs(x, y), unit="deg")

    p = GMOSImage([raw_ad])  # TODO: support for other instruments
    geotable = import_module('.geometry_conf', p.inst_lookups)
    chip_gaps = geotable.tile_gaps[raw_ad.detector_name()]

    # Test that prepare keeps the reference extenion's WCS intact
    if do_prepare:
        p.prepare()
        c = SkyCoord(*raw_ad[ref_index].wcs(x, y), unit="deg")
        assert c0.separation(c) < 1e-10 * u.arcsec

    # Test that slicing the NDData keeps the WCS valid
    if do_overscan_correct:
        xshift, _, yshift, _ = raw_ad[ref_index].data_section()
        p.overscanCorrect()
        x -= xshift
        y -= yshift
        c = SkyCoord(*raw_ad[ref_index].wcs(x, y), unit="deg")
        assert c0.separation(c) < 1e-10 * u.arcsec

    # Test that tiling doesn't affect the reference extension's WCS
    new_ref_index = 0 if (
        tile_all or raw_ad.detector_roi_setting() == 'Central Stamp') else 1
    p.tileArrays(tile_all=tile_all)
    ad = p.streams['main'][0]

    first = 0 if tile_all else (len(raw_ad) //
                                3)  # index of first raw extension
    # These extension widths are either overscan-trimmed or not, as
    # required and so no alternative logic is required
    x += sum([ext.shape[1] for ext in raw_ad[first:ref_index]])
    if tile_all and raw_ad.detector_roi_setting() != 'Central Stamp':
        x += chip_gaps // raw_ad.detector_x_bin()
    c = SkyCoord(*ad[new_ref_index].wcs(x, y), unit="deg")
    assert c0.separation(c) < 1e-10 * u.arcsec

    # Now write the file to disk and read it back in and check WCS stability
    ad.write(TEMPFILE, overwrite=True)
    ad = astrodata.open(TEMPFILE)

    c = SkyCoord(*ad[new_ref_index].wcs(x, y), unit="deg")
    assert c0.separation(c) < 1e-9 * u.arcsec

    os.remove(TEMPFILE)
Example #11
0
def test_add_object_mask_to_dq():

    try:
        import AstroFaker
    except ImportError:
        pytest.skip("AstroFaker not installed")

    ad_orig = AstroFaker.create('F2', 'IMAGE')

    #astrodata.open(os.path.join(TESTDATAPATH, 'GMOS', 'N20150624S0106_refcatAdded.fits'))
    p = GMOSImage([deepcopy(ad_orig)])
    ad = p.addObjectMaskToDQ()[0]

    for ext, ext_orig in zip(ad, ad_orig):
        assert all(
            ext.mask[ext.OBJMASK == 0] == ext_orig.mask[ext.OBJMASK == 0])
        assert all(
            ext.mask[ext.OBJMASK == 1] == ext_orig.mask[ext.OBJMASK == 1] | 1)
Example #12
0
def test_oiwfs_not_used_in_observation(caplog, filename):
    """
    Test that nothing happens when the input file does not use the OIWFS.

    Parameters
    ----------
    caplog : fixture
    filename : str
    """
    caplog.set_level(logging.DEBUG)
    file_path = download_from_archive(filename)
    ad = astrodata.open(file_path)

    p = GMOSImage([ad])
    p.addOIWFSToDQ()

    print(caplog.records)
    assert len(caplog.records) > 0
    assert any("OIWFS not used for image" in r.message for r in caplog.records)
Example #13
0
def test_warn_if_dq_does_not_exist(caplog, filename):
    """
    Test that the primitive does not run if the input file does not have a DQ
    plan.

    Parameters
    ----------
    caplog : fixture
    filename : str
    """
    caplog.set_level(logging.DEBUG)
    file_path = download_from_archive(filename)
    ad = astrodata.open(file_path)

    p = GMOSImage([ad])
    p.addOIWFSToDQ()

    assert len(caplog.records) > 0
    assert any("No DQ plane for" in r.message for r in caplog.records)
Example #14
0
    def test_measureBG(self):
        ad = astrodata.open(
            os.path.join(TESTDATAPATH, 'GMOS',
                         'N20150624S0106_refcatAdded.fits'))
        p = GMOSImage([ad])
        ad = p.measureBG()[0]
        correct = [
            726.18213, 724.36047, 727.34491, 728.49664, 728.08966, 719.83728
        ]
        for rv, cv in zip(ad.hdr['SKYLEVEL'], correct):
            assert abs(rv - cv) < 0.1, 'Wrong background level'
        assert (ad.phu['SKYLEVEL'] - 727.174) < 0.1

        f = open(logfilename, 'r')
        for line in f.readlines():
            if 'BG band' in line:
                assert line.split()[6] == 'BG80', 'Wrong BG band'

        ad.phu['REQBG'] = '50-percentile'
        ad = p.measureBG()[0]
        assert any('WARNING: BG requirement not met' in line
                   for line in f.readlines()), 'No BG warning'
Example #15
0
def test_inverse_transform_gmos(astrofaker, binning):
    # Creates GMOS images with stars at predefined points
    ad = astrofaker.create('GMOS-N')
    ad.init_default_extensions(binning=binning, overscan=False)
    for ext in ad:
        ext.add(np.random.randn(*ext.shape))
        for ystar, xstar in GMOS_STAR_LOCATIONS:
            ext.add_star(amplitude=10000, x=xstar / binning, y=ystar / binning)

    adg = transform.create_mosaic_transform(ad, geotable)
    admos = adg.transform(attributes=None, order=1)
    adout = adg.inverse_transform(admos, order=3)
    p = GMOSImage([adout])
    p.detectSources()
    adout = p.streams['main'][0]
    xbin, ybin = ad.detector_x_bin(), ad.detector_y_bin()
    for ext in adout:
        objcat = ext.OBJCAT
        objcat.sort(['Y_IMAGE'])
        for row, location in zip(objcat, GMOS_STAR_LOCATIONS):
            # OBJCAT is 1-indexed
            assert abs(row['Y_IMAGE'] - location[0] / ybin - 1) < 0.1
            assert abs(row['X_IMAGE'] - location[1] / xbin - 1) < 0.1
Example #16
0
    def test_measureCC(self, ad):

        p = GMOSImage([ad])
        ad = p.measureCC()[0]
        correct = [28.18, 28.16, 28.14, 28.11, 28.17, 28.12]
        for rv, cv in zip(ad.hdr['MEANZP'], correct):
            assert abs(rv - cv) < 0.02, 'Wrong zeropoint'

        f = open(logfilename)
        for line in f.readlines():
            if 'CC bands' in line:
                assert 'CC50, CC70' in line, 'Wrong CC bands'
        for ext in ad:
            ext.OBJCAT['MAG_AUTO'] += 0.3
        ad = p.measureCC()[0]
        correct = [c - 0.3 for c in correct]
        for rv, cv in zip(ad.hdr['MEANZP'], correct):
            assert abs(rv - cv) < 0.02, 'Wrong zeropoint after edit'
        ccwarn = False
        for line in f.readlines():
            if 'CC bands' in line:
                assert 'CC70, CC80' in line, 'Wrong CC bands after edit'
            ccwarn |= 'WARNING: CC requirement not met' in line
        assert ccwarn, 'No CC warning'
Example #17
0
def test_plot_spectra_for_qa(input_ads):
    for i, ad in enumerate(input_ads):

        # Plot single frame
        p = primitives_visualize.Visualize([])
        p.plotSpectraForQA(adinputs=[ad])

        # Gives some time to page refresh
        time.sleep(10)

        # Plot Stack
        if i >= 1:
            print('Reducing stack')
            stack_ad = GMOSImage([]).stackFrames(adinputs=input_ads[:i + 1])[0]
            p.plotSpectraForQA(adinputs=[stack_ad])

        # Gives some time to page refresh
        time.sleep(10)
Example #18
0
def test_fit_continuum_slit_image(fname, fwhm, change_working_dir):

    with change_working_dir():

        log_file = 'log_{}.log'.format(fname.replace('.fits', ''))
        logutils.config(file_name=log_file)

        ad = astrodata.open(astrodata.testing.download_from_archive(fname))
        p = GMOSImage([ad])
        p.prepare(attach_mdf=True)
        p.addDQ()
        p.trimOverscan()
        p.ADUToElectrons()
        p.mosaicDetectors()
        tbl = gt.fit_continuum(p.streams['main'][0])[0]

        assert isinstance(tbl, Table)
        assert len(tbl) == 1
        assert abs(tbl['fwhm_arcsec'].data[0] - fwhm) < 0.05
Example #19
0
def test_fit_continuum_slit_image(path_to_inputs):
    results = {'N20180118S0344': 1.32}
    for fname, fwhm in results.items():
        ad = astrodata.open(
            os.path.join(path_to_inputs, 'gt/slit_images',
                         '{}.fits'.format(fname)))
        p = GMOSImage([ad])
        p.prepare(attach_mdf=True)
        p.addDQ()
        p.trimOverscan()
        p.ADUToElectrons()
        p.mosaicDetectors()
        tbl = gt.fit_continuum(p.streams['main'][0])[0]

        assert isinstance(tbl, Table)
        assert len(tbl) == 1
        assert abs(tbl['fwhm_arcsec'].data[0] - fwhm) < 0.05