def test_fill_frac_acts_correctly(self, imageplane): fill_1 = 1. fill_2 = 0.5 autoexp_1 = AutoExposure(fill_frac=fill_1, full_well=1e5, mindit=0.011) rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": 1, "!OBS.dit": None, "!OBS.ndit": None }) autoexp_1.apply_to(imageplane) out_dit_1 = from_currsys("!OBS.dit") out_ndit_1 = from_currsys("!OBS.ndit") autoexp_2 = AutoExposure(fill_frac=fill_2, full_well=1e5, mindit=0.011) rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": 1, "!OBS.dit": None, "!OBS.ndit": None }) autoexp_2.apply_to(imageplane) out_dit_2 = from_currsys("!OBS.dit") out_ndit_2 = from_currsys("!OBS.ndit") assert out_dit_1 == fill_1 / fill_2 * out_dit_2 assert out_ndit_1 == fill_2 / fill_1 * out_ndit_2
def test_exptime_specified_by_dit_ndit(self, autoexposure, imageplane): """ Test that exptime can be given by `!OBS.dit` and `!OBS.ndit` instead of `!OBS.exptime`. """ # 1. use exptime rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": 10, "!OBS.dit": None, "!OBS.ndit": None }) autoexposure.apply_to(imageplane) dit_1 = from_currsys("!OBS.dit") ndit_1 = from_currsys("!OBS.ndit") # 2. use dit and ndit rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": None, "!OBS.dit": 5, "!OBS.ndit": 2 }) autoexposure.apply_to(imageplane) dit_2 = from_currsys("!OBS.dit") ndit_2 = from_currsys("!OBS.ndit") assert dit_1 == dit_2 assert ndit_1 == ndit_2
def test_currsys_updated_with_mode_specific_values(self, imageplane): rc.__currsys__["!OBS.detector_readout_mode"] = "fast" eff = DetectorModePropertiesSetter(**kwargs_dict()) eff.apply_to(imageplane) key_name = "!DET.mindit" assert from_currsys(key_name) == eff.mode_properties["fast"][key_name]
def test_exptime_at_least_mindit(self, imageplane): exptime = 1 mindit = 1.3 # requested exptime smaller than mindit autoexposure = AutoExposure(fill_frac=0.75, full_well=1e5, mindit=mindit) rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": exptime, "!OBS.dit": None, "!OBS.ndit": None }) autoexposure.apply_to(imageplane) dit = from_currsys("!OBS.dit") ndit = from_currsys("!OBS.ndit") assert dit == mindit assert ndit == 1
def apply_to(self, obj, **kwargs): if isinstance(obj, DetectorBase): chop_offsets = from_currsys(self.meta["chop_offsets"]) nod_offsets = from_currsys(self.meta["nod_offsets"]) if nod_offsets is None: nod_offsets = -np.array(chop_offsets) # these offsets are in pixels, not in arcsec or mm pixel_scale = float(from_currsys(self.meta["pixel_scale"])) chop_offsets_pixel = np.array(chop_offsets) / pixel_scale nod_offsets_pixel = np.array(nod_offsets) / pixel_scale image = obj.hdu.data obj.hdu.data = chop_nod_image(image, chop_offsets_pixel.astype(int), nod_offsets_pixel.astype(int)) return obj
def combine_imagehdu_fields(fov_header, src, fields_indexes, wave_min, wave_max, area, wcs_suffix=""): """ Combines a list of ImageHDUs into a single one bounded by the Header WCS Parameters ---------- fov_header : fits.Header Header from the FieldOfView src : Source object fields_indexes : list of ints Which indexes from <Source>.fields to use wave_min : float [deg] Blue spectral border wave_max : float [deg] Red spectral border area : float [m2] Area of the primary aperture wcs_suffix : str Which coordinate system to use - "" for the on-sky coordinate system - "D" for the image-plane coordinate system Returns ------- canvas_hdu : fits.ImageHDU """ image = np.zeros((fov_header["NAXIS2"], fov_header["NAXIS1"])) canvas_hdu = fits.ImageHDU(header=fov_header, data=image) spline_order = utils.from_currsys("!SIM.computing.spline_order") pixel_area = fov_header["CDELT1"] * fov_header["CDELT2"] * \ u.Unit(fov_header["CUNIT1"]).to(u.arcsec) ** 2 for ii in fields_indexes: field = src.fields[ii] if isinstance(field, fits.ImageHDU): ref = field.header["SPEC_REF"] flux = src.photons_in_range(wave_min, wave_max, area, indexes=[ref]) image = np.zeros((fov_header["NAXIS2"], fov_header["NAXIS1"])) temp_hdu = fits.ImageHDU(header=fov_header, data=image) if field.header.get("BG_SRC", False) and \ field.header["NAXIS1"] <= 1 and \ field.header["NAXIS2"] <= 1: # .. todo: check if we need to take pixel_scale into account temp_hdu.data += flux[0].value * pixel_area else: temp_hdu = imp_utils.add_imagehdu_to_imagehdu( field, temp_hdu, spline_order, wcs_suffix) temp_hdu.data *= flux[0].value canvas_hdu.data += temp_hdu.data return canvas_hdu
def test_produces_correct_values(self, autoexposure, imageplane): in_dit = 50 in_ndit = 3 exptime = in_dit * in_ndit # TODO: Change AutoExposure to read exptime like dit and ndit rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": exptime, "!OBS.dit": None, "!OBS.ndit": None }) # imageplane has 1e5 e/s, full_well is 1e5 e. To fill to 75% need: ref_dit = 0.75 autoexposure.apply_to(imageplane) out_dit = from_currsys("!OBS.dit") out_ndit = from_currsys("!OBS.ndit") assert out_dit == pytest.approx(ref_dit) assert out_dit * out_ndit == pytest.approx(exptime)
def test_detects_saturation(self, imageplane): mindit = 0.011 rc.__currsys__ = UserCommands(properties={ "!OBS.exptime": 100., "!OBS.dit": None, "!OBS.ndit": None }) autoexposure = AutoExposure(fill_frac=0.75, full_well=10., mindit=mindit) autoexposure.apply_to(imageplane) out_dit = from_currsys("!OBS.dit") assert out_dit == mindit
def test_converts_astropy_table(self): tbl = Table(data=[["!SIM.random.seed"] * 2, ["!SIM.random.seed"] * 2], names=["seeds", "seeds2"]) assert utils.from_currsys(tbl["seeds2"][1]) is None
def test_converts_dict(self): assert utils.from_currsys({"seed": "!SIM.random.seed"})["seed"] is None
def test_converts_numpy_array(self): assert utils.from_currsys(np.array( ["!SIM.random.seed"] * 2))[1] is None
def test_converts_list(self): assert utils.from_currsys(["!SIM.random.seed"] * 3)[2] is None
def test_converts_string(self): assert utils.from_currsys("!SIM.random.seed") is None
import os from synphot import SpectralElement, SourceSpectrum from scopesim.effects import SkycalcTERCurve from scopesim import rc from scopesim.utils import from_currsys local_skycalc_tests = from_currsys("!SIM.tests.run_skycalc_ter_tests") TRAVIS = True if "TRAVIS" in os.environ else local_skycalc_tests def setup_module(): rc_local_path = rc.__config__["!SIM.file.local_packages_path"] if not os.path.exists(rc_local_path): os.mkdir(rc_local_path) rc.__config__["!SIM.file.local_packages_path"] = os.path.abspath( rc_local_path) def teardown_module(): if os.path.exists("skycalc_temp.fits"): os.remove("skycalc_temp.fits") class TestInit: def test_initialises_with_nothing(self): if TRAVIS: assert isinstance(SkycalcTERCurve(), SkycalcTERCurve) def test_initialises_with_some_kwargs(self): if TRAVIS: