Example #1
0
    def test_combine(self):

        ccd1 = CCDData(np.random.normal(size=(10, 10)), unit='adu')
        ccd2 = ccd1.copy()
        ccd3 = ccd1.copy()

        combiner = Combiner([ccd1, ccd2, ccd3])
        combiner.sigma_clipping(low_thresh=2, high_thresh=5)
        combined_data = combiner.median_combine()

        np.testing.assert_equal(combined_data.data, ccd1.data)
Example #2
0
    def test_combine_masked(self):

        x = np.random.normal(size=(10, 10))
        x[5, :] = 0
        x = np.ma.masked_where(x == 0, x)

        ccd1 = CCDData(x, unit='adu')
        ccd2 = ccd1.copy()
        ccd3 = ccd1.copy()

        combiner = Combiner([ccd1, ccd2, ccd3])
        combiner.sigma_clipping(low_thresh=2, high_thresh=5)
        combined_data = combiner.median_combine()

        np.testing.assert_equal(combined_data.data, ccd1.data)
Example #3
0
class WavelengthCalibrationTests(TestCase):

    def setUp(self):
        argument_list = ['--data-path', os.getcwd(),
                         '--proc-path', os.getcwd(),
                         '--search-pattern', 'cfzsto',
                         '--output-prefix', 'w',
                         '--extraction', 'fractional',
                         '--reference-files', 'data/ref_comp',
                         '--max-targets', '3',
                         ]
        arguments = get_args(argument_list)
        self.wc = WavelengthCalibration(args=arguments)

        self.ccd = CCDData(data=np.random.random_sample(200),
                           meta=fits.Header(),
                           unit='adu')
        self.ccd = add_wcs_keys(ccd=self.ccd)
        self.ccd.header.set('SLIT',
                            value='1.0" long slit',
                            comment="slit [arcsec]")

    def test_add_wavelength_solution(self):
        self.wc.rms_error = 0.1
        self.wc.n_points = 100
        self.wc.n_rejections = 2

        self.wc.calibration_lamp = 'non-existent.fits'

        crval1 = 3977.948
        npix = 4060
        cdelt = 0.9910068

        x_axis = np.linspace(crval1,
                             crval1 + cdelt * npix,
                             npix)

        self.ccd = self.wc.add_wavelength_solution(ccd=self.ccd,
                                                   x_axis=x_axis)

        self.assertEqual(self.ccd.header['CTYPE1'], 'LINEAR')
        self.assertEqual(self.ccd.header['CRVAL1'], crval1)
        self.assertEqual(self.ccd.header['CRPIX1'], 1)
        self.assertAlmostEqual(self.ccd.header['CDELT1'], cdelt, places=3)
        self.assertEqual(self.ccd.header['DCLOG1'],
                         'REFSPEC1 = {:s}'.format(self.wc.calibration_lamp))
        self.assertEqual(self.ccd.header['GSP_WRMS'], self.wc.rms_error)
        self.assertEqual(self.ccd.header['GSP_WPOI'], self.wc.n_points)
        self.assertEqual(self.ccd.header['GSP_WREJ'], self.wc.n_rejections)

    @skip
    def test_automatic_wavelength_solution(self):
        pass

    def test__bin_reference_data(self):
        wavelength = np.linspace(3000, 7000, 4000)
        intensity = np.random.random_sample(4000)

        for i in range(1, 4):
            self.wc.serial_binning = i

            new_wavelength, new_intensity = self.wc._bin_reference_data(
                wavelength=wavelength,
                intensity=intensity)

            self.assertEqual(len(wavelength), len(intensity))
            self.assertEqual(len(new_wavelength), len(new_intensity))
            self.assertEqual(len(new_wavelength), np.floor(len(wavelength) / i))

    @skip
    def test__cross_correlation(self):
        self.wc.lamp = self.ccd.copy()
        self.wc.serial_binning = 1

        x_axis = np.arange(0, 4060, 1)

        reference = np.zeros(4060)
        gaussian = models.Gaussian1D(stddev=2)

        for i in sorted(np.random.choice(x_axis, 30)):
            gaussian.mean.value = i
            reference += gaussian(x_axis)

        offset = np.random.choice(range(1, 15), 1)[0]
        
        for slit in [1, 2, 3, 4, 5]:

            new_array = np.append(reference[offset:], np.zeros(offset))

            if slit > 3:
                box_kernel = Box1DKernel(width=slit / 0.15)
                new_array = convolve(new_array, box_kernel)

            self.assertEqual(len(reference), len(new_array))

            self.wc.lamp.header['SLIT'] = '{:d}.0" long slit'.format(slit)

            correlation_value = self.wc._cross_correlation(reference=reference,
                                                           new_array=new_array)
            self.assertEqual(correlation_value, offset)

    def test__evaluate_solution(self):

        differences = np.array([0.5] * 10)

        clipped_differences = np.ma.masked_array(differences,
                                                 mask=[0,
                                                       0,
                                                       1,
                                                       0,
                                                       0,
                                                       1,
                                                       0,
                                                       0,
                                                       1,
                                                       0])

        rms_error, n_points, n_rej = self.wc._evaluate_solution(
            clipped_differences=clipped_differences)

        self.assertEqual(rms_error, 0.5)
        self.assertEqual(n_points, 10)
        self.assertEqual(n_rej, 3)

    @skip
    def test__get_lines_in_lamp(self):
        pass

    def test__get_spectral_characteristics(self):
        self.ccd.header.set('GRATING', 'SYZY_400')
        self.ccd.header.set('GRT_ANG', 7.5)
        self.ccd.header.set('CAM_ANG', 16.1)
        self.ccd.header.set('CCDSUM', '1 1')
        self.wc.lamp = self.ccd.copy()

        spec_charact = self.wc._get_spectral_characteristics()

        self.assertIsInstance(spec_charact, dict)
        self.assertEqual(len(spec_charact), 7)

    def test_get_wsolution(self):
        self.assertIsNone(self.wc.get_wsolution())

        self.wc.wsolution = models.Chebyshev1D(degree=2)
        self.wc.wsolution.c0.value = 3977.9485
        self.wc.wsolution.c1.value = 1.00153387
        self.wc.wsolution.c2.value = -1.2891437
        self.assertIsInstance(self.wc.get_wsolution(), Model)
class WavelengthCalibrationTests(TestCase):
    def setUp(self):
        self.file_list = []
        argument_list = [
            '--data-path',
            os.getcwd(),
            '--proc-path',
            os.getcwd(),
            '--search-pattern',
            'cfzsto',
            '--output-prefix',
            'w',
            '--extraction',
            'fractional',
            '--reference-files',
            'data/ref_comp',
            '--max-targets',
            '3',
        ]
        arguments = get_args(argument_list)
        self.wc = WavelengthCalibration()

        self.ccd = CCDData(data=np.random.random_sample(200),
                           meta=fits.Header(),
                           unit='adu')
        self.ccd = add_wcs_keys(ccd=self.ccd)
        self.ccd.header.set('SLIT',
                            value='1.0_LONG_SLIT',
                            comment="slit [arcsec]")
        self.ccd.header.set('GSP_FNAM',
                            value='some_name.fits',
                            comment='Name of the current file')
        self.ccd.header.set('OBSTYPE', value='SPECTRUM', comment='Obstype')
        self.ccd.header.set('OBJECT',
                            value='An X Object',
                            comment='Some random object name')
        self.ccd.header.set('GSP_FLAT',
                            value='some_flat_file.fits',
                            comment='The name of the flat')
        self.ccd.header.set('CCDSUM', value='1 1', comment='Binning')
        self.ccd.header.set('WAVMODE', value='400 M1', comment='wavmode')

        self.lamp = self.ccd.copy()
        self.lamp.header.set('OBSTYPE',
                             value='COMP',
                             comment='Comparison lamp obstype')
        self.lamp.header.set('OBJECT', value='HgArNe')

    def tearDown(self):
        for _file in self.file_list:
            if os.path.isfile(_file):
                os.unlink(_file)

    # def test__automatic_wavelength_solution_no_match(self):
    #     self.wc.reference_data = ReferenceData(
    #         reference_dir='goodman_pipeline/data/ref_comp')
    #
    #     self.lamp.header.set('OBJECT', value='PbNa')
    #     self.wc.lamp = self.lamp
    #     self.assertRaises(NoMatchFound,
    #                       self.wc._automatic_wavelength_solution,
    #                       os.getcwd())

    def test__save_wavelength_calibrated(self):
        self.wc.sci_target_file = 'target_sci_file.fits'
        fname = self.wc._save_wavelength_calibrated(
            ccd=self.lamp,
            original_filename='file_name.fits',
            save_data_to=os.getcwd(),
            lamp=True)
        self.file_list.append(fname)
        self.assertEqual(fname, os.path.join(os.getcwd(), 'wfile_name.fits'))

        fname = self.wc._save_wavelength_calibrated(
            ccd=self.lamp,
            index=1,
            original_filename='file_name.fits',
            save_data_to=os.getcwd())
        self.file_list.append(fname)
        self.assertEqual(fname,
                         os.path.join(os.getcwd(), 'wfile_name_ws_1.fits'))

    def test__save_science_data(self):
        wavelength_solution = models.Chebyshev1D(degree=3)
        wavelength_solution.c0.value = 4419.161693945127
        wavelength_solution.c1.value = 1.321103785944705
        wavelength_solution.c2.value = -2.9766005683232e-06
        wavelength_solution.c3.value = -4.864180906701e-10
        fname = self.wc._save_science_data(
            ccd=self.ccd,
            wavelength_solution=wavelength_solution,
            save_to=os.getcwd(),
            index=None,
            plot_results=False,
            save_plots=False,
            plots=False)
        self.file_list.append(fname)

        fname_2 = self.wc._save_science_data(
            ccd=self.ccd,
            wavelength_solution=wavelength_solution,
            save_to=os.getcwd(),
            index=1,
            plot_results=False,
            save_plots=False,
            plots=False)
        self.file_list.append(fname_2)
        expected_name = os.getcwd() + '/w' + re.sub(
            '.fits', '', os.path.basename(
                self.ccd.header['GSP_FNAM'])) + "_ws_{:d}".format(1) + ".fits"

        self.assertEqual(
            fname,
            os.getcwd() + '/w' + os.path.basename(self.ccd.header['GSP_FNAM']))
        self.assertEqual(fname_2, expected_name)

    def test___call___method_wrong_ccd(self):
        self.assertRaises(AssertionError, self.wc, [], [], '', '')

    def test___call___method_wrong_comp_list(self):
        self.assertRaises(AssertionError, self.wc, self.ccd, 'comp_list', '',
                          '')

    def test___call___method_no_comparison_lamps_json(self):
        json_output = self.wc(ccd=self.ccd,
                              comp_list=[],
                              save_data_to='',
                              reference_data='',
                              json_output=True)

        self.assertEqual(json_output['error'],
                         'Unable to process without reference lamps')
        self.assertEqual(json_output['warning'], '')
        self.assertEqual(json_output['wavelength_solution'], [])

    def test___call___method_no_comparison_lamps(self):
        output = self.wc(ccd=self.ccd,
                         comp_list=[],
                         save_data_to='',
                         reference_data='',
                         json_output=False)

        self.assertIsNone(output)

    def test___call___method_one_comparison_lamps(self):
        json_output = self.wc(ccd=self.ccd,
                              comp_list=[self.lamp],
                              save_data_to='',
                              reference_data='goodman_pipeline/data/ref_comp',
                              json_output=True)

        self.assertEqual(json_output['error'],
                         'Unable to obtain wavelength solution')
        self.assertEqual(json_output['warning'], '')
        self.assertEqual(json_output['wavelength_solution'], [])

    def test___call___method_no_match_found(self):
        self.lamp.header.set('OBJECT', value='PbNa')

        self.assertRaises(NoMatchFound, self.wc, self.ccd, [self.lamp], '',
                          'goodman_pipeline/data/ref_comp')

    def test___call___method_one_solution(self):
        file_path = os.path.join(os.getcwd(), 'goodman_pipeline/data/ref_comp',
                                 'goodman_comp_1200M2_FeHeAr.fits')
        ref_lamp = CCDData.read(file_path, unit='adu')
        lamp_ccd = write_fits(
            ref_lamp,
            os.path.join(os.getcwd(), 'test_comparison_lamp.fits'),
        )
        self.file_list.append('test_comparison_lamp.fits')
        json_output = self.wc(ccd=self.ccd,
                              comp_list=[lamp_ccd],
                              save_data_to='',
                              reference_data='goodman_pipeline/data/ref_comp',
                              json_output=True)
        # print(json.dumps(json_output, indent=4))
        self.assertEqual(len(json_output['wavelength_solution']), 1)
        for _solution in json_output['wavelength_solution']:
            self.file_list.append(_solution['file_name'])
            self.file_list.append(_solution['reference_lamp'])

    def test___call___method_two_solution(self):
        file_path_1 = os.path.join(os.getcwd(),
                                   'goodman_pipeline/data/ref_comp',
                                   'goodman_comp_1200M2_FeHeAr.fits')
        file_path_2 = os.path.join(os.getcwd(),
                                   'goodman_pipeline/data/ref_comp',
                                   'goodman_comp_1200M2_CuHeAr.fits')
        ref_lamp_1 = CCDData.read(file_path_1, unit='adu')
        ref_lamp_2 = CCDData.read(file_path_2, unit='adu')
        lamp_ccd_1 = write_fits(
            ref_lamp_1,
            os.path.join(os.getcwd(), 'test_comparison_lamp_1.fits'),
        )
        lamp_ccd_2 = write_fits(
            ref_lamp_2,
            os.path.join(os.getcwd(), 'test_comparison_lamp_2.fits'),
        )
        self.file_list.append('test_comparison_lamp_1.fits')
        self.file_list.append('test_comparison_lamp_2.fits')
        json_output = self.wc(ccd=self.ccd,
                              comp_list=[lamp_ccd_1, lamp_ccd_2],
                              save_data_to='',
                              reference_data='goodman_pipeline/data/ref_comp',
                              json_output=True)
        # print(json.dumps(json_output, indent=4))
        self.assertEqual(len(json_output['wavelength_solution']), 2)
        for _solution in json_output['wavelength_solution']:
            self.file_list.append(_solution['file_name'])
            self.file_list.append(_solution['reference_lamp'])
class WavelengthCalibrationTests(TestCase):
    def setUp(self):
        argument_list = [
            '--data-path',
            os.getcwd(),
            '--proc-path',
            os.getcwd(),
            '--search-pattern',
            'cfzsto',
            '--output-prefix',
            'w',
            '--extraction',
            'fractional',
            '--reference-files',
            'data/ref_comp',
            '--max-targets',
            '3',
        ]
        arguments = get_args(argument_list)
        self.wc = WavelengthCalibration(args=arguments)

        self.ccd = CCDData(data=np.random.random_sample(200),
                           meta=fits.Header(),
                           unit='adu')
        self.ccd = add_wcs_keys(ccd=self.ccd)
        self.ccd.header.set('SLIT',
                            value='1.0" long slit',
                            comment="slit [arcsec]")

    def test_add_wavelength_solution(self):
        self.wc.rms_error = 0.1
        self.wc.n_points = 100
        self.wc.n_rejections = 2

        self.wc.calibration_lamp = 'non-existent.fits'

        crval1 = 3977.948
        npix = 4060
        cdelt = 0.9910068

        x_axis = np.linspace(crval1, crval1 + cdelt * npix, npix)

        self.ccd = self.wc.add_wavelength_solution(ccd=self.ccd, x_axis=x_axis)

        self.assertEqual(self.ccd.header['CTYPE1'], 'LINEAR')
        self.assertEqual(self.ccd.header['CRVAL1'], crval1)
        self.assertEqual(self.ccd.header['CRPIX1'], 1)
        self.assertAlmostEqual(self.ccd.header['CDELT1'], cdelt, places=3)
        self.assertEqual(self.ccd.header['DCLOG1'],
                         'REFSPEC1 = {:s}'.format(self.wc.calibration_lamp))
        self.assertEqual(self.ccd.header['GSP_WRMS'], self.wc.rms_error)
        self.assertEqual(self.ccd.header['GSP_WPOI'], self.wc.n_points)
        self.assertEqual(self.ccd.header['GSP_WREJ'], self.wc.n_rejections)

    @skip
    def test_automatic_wavelength_solution(self):
        pass

    def test__bin_reference_data(self):
        wavelength = np.linspace(3000, 7000, 4000)
        intensity = np.random.random_sample(4000)

        for i in range(1, 4):
            self.wc.serial_binning = i

            new_wavelength, new_intensity = self.wc._bin_reference_data(
                wavelength=wavelength, intensity=intensity)

            self.assertEqual(len(wavelength), len(intensity))
            self.assertEqual(len(new_wavelength), len(new_intensity))
            self.assertEqual(len(new_wavelength),
                             np.floor(len(wavelength) / i))

    @skip
    def test__cross_correlation(self):
        self.wc.lamp = self.ccd.copy()
        self.wc.serial_binning = 1

        x_axis = np.arange(0, 4060, 1)

        reference = np.zeros(4060)
        gaussian = models.Gaussian1D(stddev=2)

        for i in sorted(np.random.choice(x_axis, 30)):
            gaussian.mean.value = i
            reference += gaussian(x_axis)

        offset = np.random.choice(range(1, 15), 1)[0]

        for slit in [1, 2, 3, 4, 5]:

            new_array = np.append(reference[offset:], np.zeros(offset))

            if slit > 3:
                box_kernel = Box1DKernel(width=slit / 0.15)
                new_array = convolve(new_array, box_kernel)

            self.assertEqual(len(reference), len(new_array))

            self.wc.lamp.header['SLIT'] = '{:d}.0" long slit'.format(slit)

            correlation_value = self.wc._cross_correlation(reference=reference,
                                                           new_array=new_array)
            self.assertEqual(correlation_value, offset)

    def test__evaluate_solution(self):

        differences = np.array([0.5] * 10)

        clipped_differences = np.ma.masked_array(
            differences, mask=[0, 0, 1, 0, 0, 1, 0, 0, 1, 0])

        rms_error, n_points, n_rej = self.wc._evaluate_solution(
            clipped_differences=clipped_differences)

        self.assertEqual(rms_error, 0.5)
        self.assertEqual(n_points, 10)
        self.assertEqual(n_rej, 3)

    @skip
    def test__get_lines_in_lamp(self):
        pass

    def test__get_spectral_characteristics(self):
        self.ccd.header.set('GRATING', 'SYZY_400')
        self.ccd.header.set('GRT_ANG', 7.5)
        self.ccd.header.set('CAM_ANG', 16.1)
        self.ccd.header.set('CCDSUM', '1 1')
        self.wc.lamp = self.ccd.copy()

        spec_charact = self.wc._get_spectral_characteristics()

        self.assertIsInstance(spec_charact, dict)
        self.assertEqual(len(spec_charact), 7)

    def test_get_wsolution(self):
        self.assertIsNone(self.wc.get_wsolution())

        self.wc.wsolution = models.Chebyshev1D(degree=2)
        self.wc.wsolution.c0.value = 3977.9485
        self.wc.wsolution.c1.value = 1.00153387
        self.wc.wsolution.c2.value = -1.2891437
        self.assertIsInstance(self.wc.get_wsolution(), Model)