Beispiel #1
0
def test_resample_only(input_ad_list, caplog):
    p = GMOSLongslit(input_ad_list)
    p.resampleToCommonFrame(force_linear=False)
    _check_params(caplog.records, 'w1=508.198 w2=1088.323 dw=0.151 npix=3841')

    caplog.clear()
    adout = p.resampleToCommonFrame(dw=0.15)
    assert 'ALIGN' in adout[0].phu
    _check_params(caplog.records, 'w1=508.198 w2=1088.232 dw=0.150 npix=3868')
Beispiel #2
0
def test_resample_only_and_trim(input_ad_list, caplog):
    p = GMOSLongslit(input_ad_list)
    # Shouldn't change the first adinput
    p.resampleToCommonFrame(trim_data=True, force_linear=False)
    _check_params(caplog.records, 'w1=508.198 w2=978.802 dw=0.150 npix=3133')

    caplog.clear()
    adout = p.resampleToCommonFrame(dw=0.15)
    assert 'ALIGN' in adout[0].phu
    _check_params(caplog.records, 'w1=508.198 w2=978.802 dw=0.150 npix=3139')
Beispiel #3
0
def test_resample_and_linearize(input_ad_list, caplog):

    p = GMOSLongslit(input_ad_list)
    ads = p.resampleToCommonFrame(dw=0.15)

    assert len(ads) == 3
    assert {len(ad) for ad in ads} == {1}
    assert {ad[0].shape[0] for ad in ads} == {3869}
    assert {'ALIGN' in ad[0].phu for ad in ads}
    _check_params(caplog.records, 'w1=508.198 w2=1088.323 dw=0.150 npix=3869')
Beispiel #4
0
def test_resample_linearize_trim_and_stack(input_ad_list, caplog):
    p = GMOSLongslit(input_ad_list)
    ads = p.resampleToCommonFrame(dw=0.15, trim_data=True)

    assert len(ads) == len(test_datasets)
    assert len({ad[0].shape[0] for ad in ads}) == 1
    _check_params(caplog.records, 'w1=508.198 w2=978.802 dw=0.150 npix=3139')

    adout = p.stackFrames()
    assert len(adout) == 1
    assert len(adout[0]) == 1
    assert adout[0][0].shape[0] == 3139
Beispiel #5
0
def test_header_offset(adinputs2, caplog):
    """Test that the offset is correctly read from the headers."""
    p = GMOSLongslit(adinputs2)
    adout = p.adjustWCSToReference(method='offsets')

    for rec in caplog.records:
        assert not rec.message.startswith('WARNING - Offset from correlation')

    assert np.isclose(adout[0].phu['SLITOFF'], 0)
    assert np.isclose(adout[1].phu['SLITOFF'], -92.9368)
    assert np.isclose(adout[2].phu['SLITOFF'], -92.9368)
    assert np.isclose(adout[3].phu['SLITOFF'], 0)
Beispiel #6
0
def test_add_illum_mask_position(filename, start_row):
    file_on_disk = download_from_archive(filename)
    ad = astrodata.open(file_on_disk)

    p = GMOSLongslit([ad])
    p.prepare()
    ad = p.addIllumMaskToDQ().pop()

    # Chop off the bottom 200 rows because of the bias issue
    # and the bottom of the longslit mask for pre-Hamamatsu data
    # (larger CCDs) and  choose a middle column in case of edge effects
    actual_start_row = (ad[0].mask[200:, 100] & 64).argmax() + 200
    assert abs(start_row - actual_start_row) <= 2
Beispiel #7
0
def test_header_offset_fallback(adinputs2, caplog):
    """For this dataset the correlation method fails, and give an offset very
    different from the header one. So we check that the fallback to the header
    offset works.
    """
    p = GMOSLongslit(adinputs2)
    adout = p.adjustWCSToReference()

    # WARNING when offset is too large
    assert caplog.records[3].message.startswith('WARNING - Offset for')

    assert np.isclose(adout[0].phu['SLITOFF'], 0)
    assert np.isclose(adout[1].phu['SLITOFF'], -92.9368)
    assert np.isclose(adout[2].phu['SLITOFF'], -92.9368)
    assert np.isclose(adout[3].phu['SLITOFF'], 0, atol=0.2, rtol=0)
Beispiel #8
0
def test_config_parsing(standard_config):
    p = GMOSLongslit([])
    assert len(p.caldb) == 3
    assert p.caldb[1].name == "~/test/cal_manager.db"
    assert isinstance(p.caldb[1], cal_service.LocalDB)
    assert p.caldb[2].name == "fits"
    assert isinstance(p.caldb[2], cal_service.RemoteDB)
def test_slit_illum_correct_different_roi(change_working_dir, input_data,
                                          request):

    ad, slit_illum_ad = input_data

    assert ad.detector_roi_setting() != slit_illum_ad.detector_roi_setting()

    p = GMOSLongslit([ad])
    ad_out = p.slitIllumCorrect(slit_illum=slit_illum_ad)[0]

    for ext_out in ad_out:

        # Create output data
        data_o = np.ma.masked_array(ext_out.data, mask=ext_out.mask)

        # Bin columns
        n_rows = data_o.shape[0]
        fitter = fitting.LevMarLSQFitter()
        model = models.Chebyshev1D(c0=0.5 * n_rows,
                                   degree=2,
                                   domain=(0, n_rows))
        model.c0.fixed = True
        nbins = 10
        rows = np.arange(n_rows)

        for i in range(nbins):

            col_start = i * data_o.shape[1] // nbins
            col_end = (i + 1) * data_o.shape[1] // nbins

            cols = np.ma.mean(data_o[:, col_start:col_end], axis=1)

            fitted_model = fitter(model, rows, cols)

            # Check column is linear
            np.testing.assert_allclose(fitted_model.c2.value, 0, atol=0.001)

            # Check if slope is (almost) horizontal (< 2.5 deg)
            slope_angle = np.rad2deg(
                np.arctan(fitted_model.c1.value / (rows.size // 2)))

            assert np.abs(slope_angle) <= 1.0

    if request.config.getoption("--do-plots"):
        plot_slit_illum_correct_results(ad,
                                        ad_out,
                                        fname="test_different_roi_")
Beispiel #10
0
def test_consistent_air_and_vacuum_solutions(ad, fwidth, order, min_snr):
    p = GMOSLongslit([])
    p.viewer = geminidr.dormantViewer(p, None)

    ad_air = p.determineWavelengthSolution(
        [deepcopy(ad)], order=order, min_snr=min_snr, fwidth=fwidth,
        in_vacuo=False, **determine_wavelength_solution_parameters).pop()
    ad_vac = p.determineWavelengthSolution(
        [ad], order=order, min_snr=min_snr, fwidth=fwidth,
        in_vacuo=True, **determine_wavelength_solution_parameters).pop()
    wave_air = am.get_named_submodel(ad_air[0].wcs.forward_transform, "WAVE")
    wave_vac = am.get_named_submodel(ad_vac[0].wcs.forward_transform, "WAVE")
    x = np.arange(ad_air[0].shape[1])
    wair = wave_air(x)
    wvac = air_to_vac(wair * u.nm).to(u.nm).value
    dw = wvac - wave_vac(x)
    assert abs(dw).max() < 0.001
    def test_distortion_correction_is_applied_the_same_way(config):
        """
        Applies the same distortion correction model to both output and reference
        arcs and compares the results.
        """
        # Process the output file ---
        basename, ext = os.path.splitext(config.filename)

        basename, _ = basename.split("_")[0], basename.split("_")[1:]

        arc_basename = "{:s}_{:s}{:s}".format(basename, "distortionDetermined",
                                              ext)

        arc_name = os.path.join(config.output_dir, arc_basename)

        if not os.path.exists(arc_name):
            pytest.skip("Arc file not found: {}".format(arc_name))

        ad_out = config.ad
        p = GMOSLongslit([])

        ad_out = p.distortionCorrect(adinputs=[ad_out], arc=arc_name)[0]
        filename = ad_out.filename

        ad_out = p.determineDistortion(adinputs=[ad_out])[0]

        for ext in ad_out:
            assert "distortion_corrected" in ext.wcs.available_frames

        ad_out.write(filename=filename, overwrite=True)

        # assert False

        # # Reads the reference file ---
        # reference = os.path.join(config.ref_dir, ad_out.filename)
        #
        # if not os.path.exists(reference):
        #     pytest.fail('Reference file not found: {}'.format(reference))
        #
        # ad_ref = astrodata.open(reference)

        os.rename(filename, os.path.join(config.output_dir, filename))
Beispiel #12
0
def test_fitcoord_table_and_gwcs_match(ad, change_working_dir):
    """
    Runs determineDistortion and checks that the model in the gWCS is the same
    as the model in the FITCOORD table. The FITCOORD table is never used by
    DRAGONS.

    Parameters
    ----------
    ad: pytest.fixture (AstroData)
        Fixture that reads the filename and loads as an AstroData object.
    change_working_dir : pytest.fixture
        Fixture that changes the working directory
        (see :mod:`astrodata.testing`).
    """
    with change_working_dir():
        logutils.config(file_name='log_match_{:s}.txt'.format(ad.data_label()))
        p = GMOSLongslit([ad])
        p.viewer = geminidr.dormantViewer(p, None)
        p.determineDistortion(**fixed_parameters_for_determine_distortion)
        distortion_determined_ad = p.writeOutputs().pop()

    model = distortion_determined_ad[0].wcs.get_transform(
        "pixels", "distortion_corrected")

    fitcoord = distortion_determined_ad[0].FITCOORD
    fitcoord_model = am.table_to_model(fitcoord[0])
    fitcoord_inv = am.table_to_model(fitcoord[1])

    np.testing.assert_allclose(model[1].parameters, fitcoord_model.parameters)
    np.testing.assert_allclose(model.inverse[1].parameters,
                               fitcoord_inv.parameters)
Beispiel #13
0
def test_regression_for_determine_distortion_using_wcs(ad, change_working_dir,
                                                       ref_ad_factory):
    """
    Runs the `determineDistortion` primitive on a preprocessed data and compare
    its model with the one in the reference file. The distortion model needs to
    be reconstructed because different coefficients might return same results.

    Parameters
    ----------
    ad : pytest.fixture (AstroData)
        Fixture that reads the filename and loads as an AstroData object.
    change_working_dir : pytest.fixture
        Fixture that changes the working directory
        (see :mod:`astrodata.testing`).
    reference_ad : pytest.fixture
        Fixture that contains a function used to load the reference AstroData
        object (see :mod:`recipe_system.testing`).
    """
    with change_working_dir():
        logutils.config(
            file_name='log_fitcoord_{:s}.txt'.format(ad.data_label()))
        p = GMOSLongslit([ad])
        p.viewer = geminidr.dormantViewer(p, None)
        p.determineDistortion(**fixed_parameters_for_determine_distortion)
        distortion_determined_ad = p.writeOutputs().pop()

    ref_ad = ref_ad_factory(distortion_determined_ad.filename)
    model = distortion_determined_ad[0].wcs.get_transform(
        "pixels", "distortion_corrected")[1]
    ref_model = ref_ad[0].wcs.get_transform("pixels",
                                            "distortion_corrected")[1]

    X, Y = np.mgrid[:ad[0].shape[0], :ad[0].shape[1]]

    np.testing.assert_allclose(model(X, Y), ref_model(X, Y), atol=1)
Beispiel #14
0
def test_regression_for_determine_distortion_using_models_coefficients(
        ad, change_working_dir, ref_ad_factory, request):
    """
    Runs the `determineDistortion` primitive on a preprocessed data and compare
    its model with the one in the reference file.

    Parameters
    ----------
    ad : pytest.fixture (AstroData)
        Fixture that reads the filename and loads as an AstroData object.
    change_working_dir : pytest.fixture
        Fixture that changes the working directory
        (see :mod:`astrodata.testing`).
    reference_ad : pytest.fixture
        Fixture that contains a function used to load the reference AstroData
        object (see :mod:`recipe_system.testing`).
    request : pytest.fixture
        PyTest built-in containing command line options.
    """
    with change_working_dir():
        logutils.config(file_name='log_model_{:s}.txt'.format(ad.data_label()))
        p = GMOSLongslit([ad])
        p.viewer = geminidr.dormantViewer(p, None)
        p.determineDistortion(**fixed_parameters_for_determine_distortion)
        distortion_determined_ad = p.writeOutputs().pop()

    ref_ad = ref_ad_factory(distortion_determined_ad.filename)
    assert_have_same_distortion(distortion_determined_ad, ref_ad, atol=1)

    if request.config.getoption("--do-plots"):
        do_plots(distortion_determined_ad, ref_ad)
    def test_distortion_correct(config):
        """
        Corrects distortion on both output and reference files using the
        distortion model stored in themselves. Previous tests assures that
        these data are similar and that distortion correct is applied the same
        way. Now, this one tests the model itself.
        """
        # Recover name of the distortion corrected arc files ---
        basename = os.path.basename(config.filename)
        filename, extension = os.path.splitext(basename)
        filename = filename.split("_")[0] + "_distortionDetermined" + extension

        output = os.path.join(config.output_dir, filename)
        reference = os.path.join(config.ref_dir, filename)

        if not os.path.exists(output):
            pytest.fail("Processed arc file not found: {}".format(output))

        if not os.path.exists(reference):
            pytest.fail(
                "Processed reference file not found: {}".format(reference))

        p = GMOSLongslit([])

        ad_out = astrodata.open(output)
        ad_out_corrected_with_out = p.distortionCorrect([ad_out],
                                                        arc=output)[0]
        ad_out_corrected_with_ref = p.distortionCorrect([ad_out],
                                                        arc=reference)[0]

        ad_out_corrected_with_out.write(
            overwrite=True,
            filename=os.path.join(config.output_dir,
                                  ad_out_corrected_with_out.filename),
        )

        for ext_out, ext_ref in zip(ad_out_corrected_with_out,
                                    ad_out_corrected_with_ref):
            np.testing.assert_allclose(ext_out.data, ext_ref.data)
    def test_distortionCorrect_works_when_using_FullROI_on_CentralROI(
            path_to_outputs):
        """
        Test if a model obtained in a Full Frame ROI can be applied to a Central
        Spectra ROI.
        """
        class Config:
            def __init__(self, name):
                sub_path, basename = os.path.split(name)

                basename, ext = os.path.splitext(basename)
                basename = basename + "_distortionDetermined.fits"

                self._filename = basename
                self.output_dir = os.path.join(path_to_outputs, sub_path)
                self.full_name = os.path.join(self.output_dir, self._filename)

            @property
            def filename(self):
                return self._filename

            @filename.setter
            def filename(self, name):
                self._filename = name
                self.full_name = os.path.join(self.output_dir, self._filename)

        # B600:0.500 HAM, ROI="Central Spectrum" ---
        cs = Config("N20171016S0010.fits")
        cs.ad = astrodata.open(os.path.join(cs.output_dir, cs.filename))

        # B600:0.500 HAM, ROI="Full Frame" ---
        ff = Config("N20171016S0127.fits")

        # Apply full frame roi to central-spect roi
        p = GMOSLongslit([])
        cs.ad = p.distortionCorrect(adinputs=[cs.ad], arc=ff.full_name)[0]
        cs.filename = cs.filename.replace(".fits", "_fromFullFrame.fits")
        cs.ad.write(filename=cs.full_name, overwrite=True)
Beispiel #17
0
def test_correlation_and_w1_w2(adinputs, caplog):
    add_fake_offset(adinputs, offset=10)
    p = GMOSLongslit(adinputs)
    adout = p.adjustWCSToReference()

    assert adout[1].phu['SLITOFF'] == -10
    assert adout[2].phu['SLITOFF'] == -20

    p.resampleToCommonFrame(dw=0.15, w1=700, w2=850)
    _check_params(caplog.records, 'w1=700.000 w2=850.000 dw=0.150 npix=1001')

    adstack = p.stackFrames()
    assert adstack[0][0].shape == (512, 1001)
Beispiel #18
0
def test_correlation_non_linearize(adinputs, caplog):
    add_fake_offset(adinputs, offset=10)
    p = GMOSLongslit(adinputs)
    adout = p.adjustWCSToReference()

    assert adout[1].phu['SLITOFF'] == -10
    assert adout[2].phu['SLITOFF'] == -20

    p.resampleToCommonFrame(force_linear=False)
    _check_params(caplog.records, 'w1=508.198 w2=1088.323 dw=0.151 npix=3841')
    caplog.clear()
    adout = p.resampleToCommonFrame(dw=0.15)
    assert 'ALIGN' in adout[0].phu
    _check_params(caplog.records, 'w1=508.198 w2=1088.232 dw=0.150 npix=3868')

    adstack = p.stackFrames()
    assert adstack[0][0].shape == (512, 3868)
Beispiel #19
0
def test_correlation_and_trim(adinputs, caplog):
    add_fake_offset(adinputs, offset=10)
    p = GMOSLongslit(adinputs)
    adout = p.adjustWCSToReference()

    assert adout[1].phu['SLITOFF'] == -10
    assert adout[2].phu['SLITOFF'] == -20

    p.resampleToCommonFrame(dw=0.15, trim_data=True)
    _check_params(caplog.records, 'w1=508.198 w2=978.802 dw=0.150 npix=3139')

    ad = p.stackFrames()[0]
    assert ad[0].shape == (512, 3139)

    caplog.clear()
    ad = p.findSourceApertures(max_apertures=1)[0]
    assert len(ad[0].APERTURE) == 1
    np.testing.assert_allclose(ad[0].APERTURE['c0'], 260.8, atol=0.25)

    ad = p.extract1DSpectra()[0]
    assert ad[0].shape == (3139, )
Beispiel #20
0
def test_correlation(adinputs, caplog):
    add_fake_offset(adinputs, offset=10)
    p = GMOSLongslit(adinputs)
    adout = p.adjustWCSToReference()

    assert adout[1].phu['SLITOFF'] == -10
    assert adout[2].phu['SLITOFF'] == -20

    p.resampleToCommonFrame(dw=0.15)
    _check_params(caplog.records, 'w1=508.198 w2=1088.323 dw=0.150 npix=3869')

    ad = p.stackFrames()[0]
    assert ad[0].shape == (512, 3869)

    caplog.clear()
    ad = p.findSourceApertures(max_apertures=1)[0]
    assert len(ad[0].APERTURE) == 1
    #assert caplog.records[3].message == 'Found sources at rows: 260.8'
    np.testing.assert_allclose(ad[0].APERTURE['c0'], 260.8, atol=0.25)

    ad = p.extract1DSpectra()[0]
    assert ad[0].shape == (3869, )
Beispiel #21
0
def test_regression_determine_wavelength_solution(ad, fwidth, order, min_snr,
                                                  caplog, change_working_dir,
                                                  ref_ad_factory, request):
    """
    Make sure that the wavelength solution gives same results on different
    runs.
    """
    caplog.set_level(logging.INFO, logger="geminidr")

    with change_working_dir():
        logutils.config(
            file_name='log_regress_{:s}.txt'.format(ad.data_label()))
        p = GMOSLongslit([ad])
        p.viewer = geminidr.dormantViewer(p, None)

        p.determineWavelengthSolution(
            order=order,
            min_snr=min_snr,
            fwidth=fwidth,
            **determine_wavelength_solution_parameters)

        wcalibrated_ad = p.writeOutputs().pop()

        for record in caplog.records:
            if record.levelname == "WARNING":
                assert "No acceptable wavelength solution found" not in record.message

    ref_ad = ref_ad_factory(wcalibrated_ad.filename)
    model = am.get_named_submodel(wcalibrated_ad[0].wcs.forward_transform,
                                  "WAVE")
    ref_model = am.get_named_submodel(ref_ad[0].wcs.forward_transform, "WAVE")

    x = np.arange(wcalibrated_ad[0].shape[1])
    wavelength = model(x)
    ref_wavelength = ref_model(x)

    pixel_scale = wcalibrated_ad[0].pixel_scale()  # arcsec / px
    slit_size_in_arcsec = float(wcalibrated_ad[0].focal_plane_mask().replace(
        'arcsec', ''))
    slit_size_in_px = slit_size_in_arcsec / pixel_scale
    dispersion = abs(
        wcalibrated_ad[0].dispersion(asNanometers=True))  # nm / px

    tolerance = 0.5 * (slit_size_in_px * dispersion)
    np.testing.assert_allclose(wavelength, ref_wavelength, rtol=tolerance)

    if request.config.getoption("--do-plots"):
        do_plots(wcalibrated_ad)
Beispiel #22
0
def test_write_spectrum(ad, output_format, extension, input_format,
                        change_working_dir):

    with change_working_dir():
        nfiles = len(glob("*"))
        p = GMOSLongslit([ad])
        p.write1DSpectra(apertures=1,
                         format=output_format,
                         extension=extension)
        assert len(glob("*")) == nfiles + 1
        t = Table.read(ad.filename.replace(".fits", f"_001.{extension}"),
                       format=input_format)
        assert len(t) == ad[0].data.size
        np.testing.assert_allclose(t["data"].data, ad[0].data, atol=1e-9)
        p.write1DSpectra(apertures=None,
                         format=output_format,
                         extension=extension,
                         overwrite=True)
        assert len(glob("*")) == nfiles + len(ad)
def test_slit_illum_correct_without_slit_illumination(astrofaker):
    in_ad = astrofaker.create("GMOS-S", mode="SPECT")
    p = GMOSLongslit([in_ad])
    with pytest.raises(NotImplementedError):
        p.slitIllumCorrect()
def test_dont_do_slit_illum(astrofaker):
    in_ad = astrofaker.create("GMOS-S", mode="SPECT")
    p = GMOSLongslit([in_ad])
    out_ad = p.slitIllumCorrect(do_illum=False)[0]
    for in_ext, out_ext in zip(in_ad, out_ad):
        assert np.testing.assert_equal(in_ext.data, out_ext.data)
def create_quartz_inputs():
    """
    Creates input data for tests using pre-processed twilight flat data 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.
    """
    associated_calibrations = {
        "N20200715S0059.fits": {
            "quartz": ["N20200715S0059.fits"],
        },
        "S20130601S0121.fits": {
            "quartz": ["S20130601S0121.fits"],
        },
        "S20190204S0081.fits": {
            "quartz": ["S20190204S0081.fits"],
        },
    }

    root_path = os.path.join("./dragons_test_inputs/")
    module_path = "geminidr/gmos/longslit/test_slit_illum_correct/inputs"
    path = os.path.join(root_path, module_path)
    os.makedirs(path, exist_ok=True)

    cwd = os.getcwd()
    os.chdir(path)
    print('Current working directory:\n    {:s}'.format(os.getcwd()))

    for filename, cals in associated_calibrations.items():

        print('Download raw files')
        quartz_path = [download_from_archive(f) for f in cals['quartz']]

        quartz_ad = astrodata.open(quartz_path[0])
        data_label = quartz_ad.data_label()

        print('Reducing quartz lamp:')
        logutils.config(file_name='log_quartz_{}.txt'.format(data_label))
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            p = GMOSLongslit([astrodata.open(f) for f in quartz_path])
            p.prepare()
            p.addDQ(static_bpm=None)
            p.addVAR(read_noise=True)
            p.overscanCorrect()
            # p.biasCorrect(bias=bias_master)
            p.ADUToElectrons()
            p.addVAR(poisson_noise=True)
            p.stackFrames()

            # Write non-mosaicked data
            p.writeOutputs(suffix="_quartz", strip=True)

    os.chdir(cwd)
def create_twilight_inputs():
    """
    Creates input data for tests using pre-processed twilight flat data 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.
    """

    associated_calibrations = {
        "S20190204S0006.fits": {
            "bias": [
                "S20190203S0110.fits", "S20190203S0109.fits",
                "S20190203S0108.fits", "S20190203S0107.fits",
                "S20190203S0106.fits"
            ],
            "twilight": ["S20190204S0006.fits"],
        },
        "N20190103S0462.fits": {
            "bias": [
                "N20190102S0531.fits", "N20190102S0530.fits",
                "N20190102S0529.fits", "N20190102S0528.fits",
                "N20190102S0527.fits"
            ],
            "twilight": ["N20190103S0462.fits", "N20190103S0463.fits"],
        },
        "N20190327S0056.fits": {
            "bias": [
                "N20190327S0098.fits", "N20190327S0099.fits",
                "N20190327S0100.fits", "N20190327S0101.fits",
                "N20190327S0102.fits"
            ],
            "twilight": ["N20190327S0056.fits"],
        },
        "S20130602S0005.fits": {
            "bias": [
                "S20130601S0161.fits",
                "S20130601S0160.fits",
                "S20130601S0159.fits",
                "S20130601S0158.fits",
                "S20130601S0157.fits",
            ],
            "twilight": ["S20130602S0005.fits"],
        },
        "N20190602S0306.fits": {
            "bias": [
                "N20190601S0648.fits",
                "N20190601S0647.fits",
                "N20190601S0646.fits",
                "N20190601S0645.fits",
                "N20190601S0644.fits",
            ],
            "twilight": ["N20190602S0306.fits"],
        }
    }

    root_path = os.path.join("./dragons_test_inputs/")
    module_path = "geminidr/gmos/longslit/test_slit_illumination_correct/inputs"
    path = os.path.join(root_path, module_path)
    os.makedirs(path, exist_ok=True)
    cwd = os.getcwd()
    os.chdir(path)
    print('Current working directory:\n    {:s}'.format(os.getcwd()))

    for filename, cals in associated_calibrations.items():

        print('Download raw files')
        bias_path = [download_from_archive(f) for f in cals['bias']]
        twilight_path = [download_from_archive(f) for f in cals['twilight']]

        twilight_ad = astrodata.open(twilight_path[0])
        data_label = twilight_ad.data_label()

        print('Reducing BIAS for {:s}'.format(data_label))
        logutils.config(file_name='log_bias_{}.txt'.format(data_label))
        bias_reduce = Reduce()
        bias_reduce.files.extend(bias_path)
        bias_reduce.runr()
        bias_master = bias_reduce.output_filenames.pop()
        del bias_reduce

        print('Reducing twilight flat:')
        logutils.config(file_name='log_twilight_{}.txt'.format(data_label))
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            p = GMOSLongslit([astrodata.open(f) for f in twilight_path])
            p.prepare()
            p.addDQ(static_bpm=None)
            p.addVAR(read_noise=True)
            p.overscanCorrect()
            p.biasCorrect(bias=bias_master)
            p.ADUToElectrons()
            p.addVAR(poisson_noise=True)
            p.stackFrames()

            # Write non-mosaicked data
            twilight = p.writeOutputs(suffix="_twilight", strip=True)[0]

            # Write mosaicked data
            p = GMOSLongslit([twilight])
            p.makeSlitIllum()
            p.writeOutputs()

    os.chdir(cwd)
    return
Beispiel #27
0
def test_resample_error_with_all(input_ad_list, caplog):
    p = GMOSLongslit(input_ad_list)
    expected_error = "Maximum 3 of w1, w2, dw, npix must be specified"
    with pytest.raises(ValueError, match=expected_error):
        p.resampleToCommonFrame(dw=0.15, w1=700, w2=850, npix=1001)
Beispiel #28
0
def test_resample_and_linearize_with_npix(input_ad_list, caplog):
    p = GMOSLongslit(input_ad_list)
    p.resampleToCommonFrame(dw=0.15, w1=700, npix=1001)
    _check_params(caplog.records, 'w1=700.000 w2=850.000 dw=0.150 npix=1001')
Beispiel #29
0
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 recipe_system.reduction.coreReduce import Reduce
    from gempy.utils import logutils

    associated_calibrations = {
        "S20190808S0048.fits": {
            "arcs": ["S20190808S0167.fits"]
        },
        "S20190808S0049.fits": {
            "arcs": ["S20190808S0168.fits"]
        },
        # "S20190808S0052.fits": {"arcs": ["S20190808S0165.fits"]}, # Can't find aperture
        "S20190808S0053.fits": {
            "arcs": ["S20190808S0169.fits"]
        },
    }

    root_path = os.path.join("./dragons_test_inputs/")
    module_path = "geminidr/gmos/spect/{}".format(__file__.split('.')[0])
    path = os.path.join(root_path, module_path)
    os.makedirs(path, exist_ok=True)
    os.chdir(path)
    os.makedirs("./inputs", exist_ok=True)
    print('Current working directory:\n    {:s}'.format(os.getcwd()))

    for filename, cals in associated_calibrations.items():

        print('Downloading files...')
        sci_path = download_from_archive(filename)
        arc_path = [download_from_archive(f) for f in cals['arcs']]

        sci_ad = astrodata.open(sci_path)
        data_label = sci_ad.data_label()

        print('Reducing ARC for {:s}'.format(data_label))
        logutils.config(file_name='log_arc_{}.txt'.format(data_label))
        arc_reduce = Reduce()
        arc_reduce.files.extend(arc_path)
        arc_reduce.runr()
        arc = arc_reduce.output_filenames.pop()

        print('Reducing pre-processed data:')
        logutils.config(file_name='log_{}.txt'.format(data_label))
        p = GMOSLongslit([sci_ad])
        p.prepare()
        p.addDQ(static_bpm=None)
        p.addVAR(read_noise=True)
        p.overscanCorrect()
        p.ADUToElectrons()
        p.addVAR(poisson_noise=True)
        p.mosaicDetectors()
        p.distortionCorrect(arc=arc)
        p.findSourceApertures(max_apertures=1)
        p.skyCorrectFromSlit()
        p.traceApertures()
        p.extract1DSpectra()

        os.chdir("inputs/")
        _ = p.writeOutputs().pop()
        os.chdir("../")
Beispiel #30
0
def create_inputs():
    """
    Create inputs for `test_plot_spectra_for_qa_single_frame`.

    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 glob
    import os
    from geminidr.gmos.primitives_gmos_longslit import GMOSLongslit
    from gempy.utils import logutils
    from recipe_system.reduction.coreReduce import Reduce
    from recipe_system.utils.reduce_utils import normalize_ucals

    cwd = os.getcwd()
    path = f"./dragons_test_inputs/geminidr/core/{__file__.split('.')[0]}/"
    os.makedirs(path, exist_ok=True)
    os.chdir(path)

    os.makedirs("inputs/", exist_ok=True)

    for raw_list, bias_list, quartz_list, arc_list in single_aperture_data:

        if all([
                os.path.exists(f"inputs/{s.split('.')[0]}_extracted.fits")
                for s in raw_list
        ]):
            print("Skipping already created input.")
            continue

        raw_paths = [download_from_archive(f) for f in raw_list]
        bias_paths = [download_from_archive(f) for f in bias_list]
        quartz_paths = [download_from_archive(f) for f in quartz_list]
        arc_paths = [download_from_archive(f) for f in arc_list]

        cals = []
        raw_ads = [astrodata.open(p) for p in raw_paths]
        data_label = raw_ads[0].data_label()
        print('Current working directory:\n    {:s}'.format(os.getcwd()))

        if len(bias_paths):
            logutils.config(file_name='log_bias_{}.txt'.format(data_label))
            r = Reduce()
            r.files.extend(bias_paths)
            r.runr()
            master_bias = r.output_filenames.pop()
            cals.append(f"processed_bias:{master_bias}")
            del r
        else:
            master_bias = None

        if len(quartz_paths):
            logutils.config(file_name='log_quartz_{}.txt'.format(data_label))
            r = Reduce()
            r.files.extend(quartz_paths)
            r.ucals = normalize_ucals(r.files, cals)
            r.runr()
            master_quartz = r.output_filenames.pop()
            cals.append(f"processed_flat:{master_quartz}")
            del r
        else:
            master_quartz = None

        logutils.config(file_name='log_arc_{}.txt'.format(data_label))
        r = Reduce()
        r.files.extend(arc_paths)
        r.ucals = normalize_ucals(r.files, cals)
        r.runr()
        master_arc = r.output_filenames.pop()

        logutils.config(file_name='log_{}.txt'.format(data_label))
        p = GMOSLongslit(raw_ads)
        p.prepare()
        p.addDQ(static_bpm=None)
        p.addVAR(read_noise=True)
        p.overscanCorrect()
        p.biasCorrect(do_bias=master_bias is not None, bias=master_bias)
        p.ADUToElectrons()
        p.addVAR(poisson_noise=True)
        p.flatCorrect(do_flat=master_quartz is not None, flat=master_quartz)
        p.QECorrect(arc=master_arc)
        p.distortionCorrect(arc=master_arc)
        p.findSourceApertures(max_apertures=3)
        p.skyCorrectFromSlit()
        p.traceApertures()
        p.extract1DSpectra()
        p.linearizeSpectra()

        [os.remove(s) for s in glob.glob("*_arc.fits")]
        [os.remove(s) for s in glob.glob("*_bias.fits")]
        [os.remove(s) for s in glob.glob("*_flat.fits")]
        [os.remove(s) for s in glob.glob("*_mosaic.fits")]

        os.chdir("inputs/")
        print("\n\n    Writing processed files for tests into:\n"
              "    {:s}\n\n".format(os.getcwd()))
        _ = p.writeOutputs()
        os.chdir("../")

    os.chdir(cwd)