def test_WFI_filters(): wi = wfirst.WFI() filter_list = wi.filter_list for filter in filter_list: wi = wfirst.WFI() wi.filter = filter wi.calc_psf(fov_pixels=4, oversample=1, nlambda=3)
def test_WFI_chooses_pupil_masks(): wfi = wfirst.WFI() def autopupil(): """Helper to trigger pupil selection in testing""" wavelengths, _ = wfi._getWeights() wfi._validateConfig(wavelengths=wavelengths) wfi.filter = 'Z087' autopupil() assert wfi.pupil == wfi._unmasked_pupil_path, "WFI did not select unmasked pupil for Z087" wfi.filter = 'H158' autopupil() assert wfi.pupil == wfi._masked_pupil_path, "WFI did not select masked pupil for H158" wfi.filter = 'Z087' autopupil() assert wfi.pupil == wfi._unmasked_pupil_path, "WFI did not re-select unmasked pupil for Z087" def _test_filter_pupil(filter_name, expected_pupil): wfi.filter = 'Z087' autopupil() wfi.filter = filter_name autopupil() assert wfi.pupil == expected_pupil, "Expected pupil {} " \ "for filter {}".format(filter_name, expected_pupil) _test_filter_pupil('Y106', wfi._unmasked_pupil_path) _test_filter_pupil('J129', wfi._unmasked_pupil_path) _test_filter_pupil('H158', wfi._masked_pupil_path) _test_filter_pupil('F184', wfi._masked_pupil_path) _test_filter_pupil('W149', wfi._masked_pupil_path)
def test_WFI_includes_aberrations(): wfi = wfirst.WFI() wfi.detector = 'SCA01' osys = wfi._getOpticalSystem() assert isinstance(osys[2], wfirst.FieldDependentAberration), ( "Third plane of WFIRST WFI optical system should be the " "field dependent aberration virtual optic")
def test_WFI_psf(): """ Just test that instantiating WFI works and can compute a PSF without raising any exceptions """ wi = wfirst.WFI() wi.calc_psf(fov_pixels=4)
def test_WFI_detector_position_setter(): wfi = wfirst.WFI() wfi.detector = 'SCA01' valid_pos = (4000, 1000) wfi.detector_position = valid_pos assert wfi._detectors[wfi._detector].field_position == valid_pos, ( "Setting field position through Instrument.detector_position did not update field_position " "for the detector's aberration optic") assert wfi.detector_position == valid_pos, "`detector_position` getter doesn't reflect " \ "assignment to setter"
def resetPSF(self): import webbpsf if self.filter not in self.FILTERS: raise ValueError("Filter %s is not a valid WFI filter" % (self.filter)) have_psf = False if os.path.exists(os.path.join(self.out_path, "psf_cache")): if os.path.exists(os.path.join(self.out_path, "psf_cache", "psf_{}_{}_{}.fits".format("WFI", self.filter, self.oversample))): with pyfits.open(os.path.join(self.out_path, "psf_cache", "psf_{}_{}_{}.fits".format("WFI", self.filter, self.oversample))) as psf: if psf[0].header['VERSION'] >= webbpsf.__version__ and (self.psf_commands is None or self.psf_commands == ''): psf_scale = [psf[0].header["PIXELSCL"], psf[0].header["PIXELSCL"]] self.psf = AstroImage(data=psf[0].data, scale=psf_scale, ra=self.ra, dec=self.dec, pa=self.pa, detname="WFI {} PSF".format(self.filter), logger=self.logger) have_psf = True if not have_psf: base_state = self.getState() self.updateState(base_state+"<br /><span class='indented'>Generating PSF</span>") from webbpsf import wfirst ins = wfirst.WFI() if self.psf_commands is not None and self.psf_commands != '': for attribute,value in self.psf_commands.iteritems(): setattr(ins,attribute,value) ins.filter = self.filter max_safe_size = int(np.floor(30. * self.PHOTPLAM[self.filter] / (2. * self.SCALE[0]))) max_ins_size = max(self.DETECTOR_SIZE) * self.oversample max_conv_size = int(np.floor(2048 / self.oversample)) self._log("info", "PSF choosing between {}, {}, and {}".format(max_safe_size, max_ins_size, max_conv_size)) if hasattr(ins, 'calc_psf'): ins.calcPSF = ins.calc_psf psf = ins.calcPSF(oversample=self.oversample, fov_pixels=min(max_safe_size, max_ins_size, max_conv_size), normalize='last') self._log("info", "PSF Total Flux: {}".format(np.sum(psf[0].data))) psf[0].header['VERSION'] = webbpsf.__version__ if os.path.exists(os.path.join(self.out_path, "psf_cache")): dest = os.path.join(self.out_path, "psf_cache", "psf_{}_{}_{}.fits".format("WFI", self.filter, self.oversample)) pyfits.writeto(dest, psf[0].data, header=psf[0].header, overwrite=True) psf_scale = [psf[0].header["PIXELSCL"], psf[0].header["PIXELSCL"]] self.psf = AstroImage(data=psf[0].data, scale=psf_scale, ra=self.ra, dec=self.dec, pa=self.pa, detname="WFI %s PSF" % (self.filter), logger=self.logger) self.updateState(base_state)
def test_WFI_fwhm(): """ Test that computed PSFs are physically realistic, at least relatively. Loose test... """ wfi = wfirst.WFI() wfi.pupilopd = None wfi.options['jitter'] = None wfi.filter = 'F062' fwhm_f062 = measure_fwhm(wfi.calc_psf(oversample=6)) wfi.filter = 'F184' fwhm_f184 = measure_fwhm(wfi.calc_psf(oversample=6)) assert (4.0 > fwhm_f184 / fwhm_f062 > 2.0)
def test_WFI_limits_interpolation_range(): wfi = wfirst.WFI() det = wfi._detectors['SCA01'] det.get_aberration_terms(1.29e-6) det.field_position = (0, 0) with pytest.raises(RuntimeError) as excinfo: det.get_aberration_terms(1.29e-6) assert 'out-of-bounds field point' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds field point") with pytest.raises(RuntimeError) as excinfo: det.get_aberration_terms(1.29e-6) assert 'out-of-bounds field point' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds field point") det.field_position = (2048, 2048) with pytest.raises(RuntimeError) as excinfo: det.get_aberration_terms(5e-6) assert 'wavelength outside the range' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds wavelength")
def test_WFI_limits_interpolation_range(): wfi = wfirst.WFI() det = wfi._detectors['SCA01'] det.get_aberration_terms(1.29e-6) det.field_position = (0, 0) det.get_aberration_terms(1.29e-6) with pytest.raises(ValueError) as excinfo: det.field_position = (500000, 0) assert 'Requested pixel_x position' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds field point") with pytest.raises(ValueError) as excinfo: det.field_position = (-1, 0) assert 'Requested pixel_x position' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds field point") with pytest.raises(ValueError) as excinfo: det.field_position = (0, 500000) assert 'Requested pixel_y position' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds field point") with pytest.raises(ValueError) as excinfo: det.field_position = (0, -1) assert 'Requested pixel_y position' in str(excinfo.value), ( "FieldDependentAberration did not error on out-of-bounds field point") det.field_position = (2048, 2048) # Test the get_aberration_terms function uses approximated wavelength when # called with an out-of-bound wavelength. assert allclose( det.get_aberration_terms(2.0e-6), det.get_aberration_terms(2.5e-6) ), ("Aberration outside wavelength range did not return closest value.") assert allclose( det.get_aberration_terms(0.48e-6), det.get_aberration_terms(0.40e-6) ), ("Aberration outside wavelength range did not return closest value.")
import astropy import astropy.io.fits as fits import webbpsf from webbpsf import wfirst import matplotlib import matplotlib.pyplot as pyplot import numpy as np wfi = wfirst.WFI() fs = wfi.filter_list print(fs) print(wfi.detector) print(wfi.detector_position) fig = pyplot.figure(figsize=(8.0, 4.0), dpi=300) fig.subplots_adjust(left=0.0, bottom=0.0, top=1.0, right=1.0, hspace=0.0, wspace=0.0) for i, fname in enumerate(fs): wfi.filter = fname this_psf = wfi.calc_psf() this_psf.writeto('WFI_' + fname + '_SCA01_center_psf_phaseb.fits', overwrite=True) ax = fig.add_subplot(2, 4, i + 1)
def test_WFI_pupil_controller(): wfi = wfirst.WFI() for detector in wfi.detector_list: wfi.detector = detector detector_cropped = detector[:3] + str(int( (detector[3:]))) # example "SCA01" -> "SCA1" unmasked_pupil_path = os.path.join( wfi._pupil_controller._pupil_basepath, '{}_rim_mask.fits.gz'.format(detector_cropped)) masked_pupil_path = os.path.join( wfi._pupil_controller._pupil_basepath, '{}_full_mask.fits.gz'.format(detector_cropped)) assert os.path.isfile( unmasked_pupil_path), "Pupil file missing {}".format( unmasked_pupil_path) assert os.path.isfile( masked_pupil_path), "Pupil file missing {}".format( masked_pupil_path) # Test detector change was successful assert wfi.detector == detector, "WFI detector was not set correctly" assert wfi._unmasked_pupil_path == unmasked_pupil_path, "unmasked_pupil_path was not set correctly" assert wfi._masked_pupil_path == masked_pupil_path, "masked_pupil_path was not set correctly" assert wfi.pupil in [unmasked_pupil_path, masked_pupil_path], "pupil was not set correctly" # Test mask overriding wfi.pupil_mask = MASKED_FLAG assert wfi.pupil == masked_pupil_path, "pupil was not set correctly" assert wfi._pupil_controller.auto_pupil is False, "auto_pupil is active after user override" assert wfi._pupil_controller._pupil_mask == wfi.pupil_mask, "pupil mask was not set correctly" wfi.pupil_mask = UNMASKED_FLAG assert wfi.pupil == unmasked_pupil_path, "pupil was not set correctly" assert wfi._pupil_controller.auto_pupil is False, "auto_pupil is active after user override" assert wfi._pupil_controller._pupil_mask == wfi.pupil_mask, "pupil mask was not set correctly" wfi.pupil_mask = AUTO_FLAG assert wfi._pupil_controller.auto_pupil is True, "auto_pupil is inactive after mask is set to AUTO" assert wfi._pupil_controller._pupil_mask == wfi.pupil_mask, "pupil mask was not set correctly" # Test filters for filter in wfi.filter_list: wfi.filter = filter if filter in wfi._pupil_controller._masked_filters: assert wfi.pupil == masked_pupil_path, \ "Pupil did not set to correct value according to filter {}".format(filter) else: assert wfi.pupil == unmasked_pupil_path, \ "Pupil did not set to correct value according to filter {}".format(filter) # Test calculating a single PSF wfi = wfirst.WFI() wfi.detector = detector valid_pos = (4000, 1000) wfi.detector_position = valid_pos wfi.pupil_mask = "COLD_PUPIL" assert wfi.pupil == masked_pupil_path, "Pupil did not set to correct value according to override" wfi.calc_psf(fov_pixels=4) assert wfi.pupil == masked_pupil_path, "Pupil did not set to correct value according to override"