def test_dice9_bad(): with pytest.raises(ValueError): dither.get_dither_positions(base_position=42, n_positions=42, pattern=dither.dice9, pattern_offset=300 * u.arcsecond) with pytest.raises(ValueError): dither.get_dither_positions(base_position="16h52m42.2s -38d37m12s", n_positions=42, pattern=dither.dice9)
def test_dice9_string(): base = "16h52m42.2s -38d37m12s" positions = dither.get_dither_positions(base_position=base, n_positions=12, pattern=dither.dice9, pattern_offset=30 * u.arcminute) base = SkyCoord(base) assert isinstance(positions, SkyCoord) assert len(positions) == 12 # postion 0 should be the base position assert positions[0].separation(base) < Angle(1e12 * u.degree) # With no random offset positions 9, 10, 11 should be the same as 0, 1, 2 assert positions[0:3].to_string() == positions[9:12].to_string() # Position 1 should be 30 arcminute offset from base, in declination direction only assert base.spherical_offsets_to( positions[1])[0].radian == pytest.approx(Angle(0 * u.degree).radian) assert base.spherical_offsets_to( positions[1])[1].radian == pytest.approx(Angle(0.5 * u.degree).radian) # Position 3 should be 30 arcminute offset from base in RA only. assert base.spherical_offsets_to( positions[3])[0].radian == pytest.approx(Angle(0.5 * u.degree).radian) assert base.spherical_offsets_to( positions[3])[1].radian == pytest.approx(Angle(0 * u.degree).radian)
def test_custom_pattern(): base = SkyCoord("16h52m42.2s -38d37m12s") cross = ((0, 0), (0, 1), (1, 0), (0, -1), (-1, 0)) positions = dither.get_dither_positions(base_position=base, n_positions=12, pattern=cross, pattern_offset=1800 * u.arcsecond) assert isinstance(positions, SkyCoord) assert len(positions) == 12 # postion 0 should be the base position assert positions[0].separation(base) < Angle(1e12 * u.degree) # With no random offset positions 5, 6, 7 should be the same as 0, 1, 2 assert positions[0:3].to_string() == positions[5:8].to_string() # Position 3 should be 30 arcminute offset from base, in declination direction only assert base.spherical_offsets_to( positions[3])[0].radian == pytest.approx(Angle(0 * u.degree).radian) assert base.spherical_offsets_to(positions[3])[1].radian == pytest.approx( Angle(-0.5 * u.degree).radian) # Position 4 should be 30 arcminute offset from base in RA only. assert base.spherical_offsets_to(positions[4])[0].radian == pytest.approx( Angle(-0.5 * u.degree).radian) assert base.spherical_offsets_to( positions[4])[1].radian == pytest.approx(Angle(0 * u.degree).radian)
def test_plot(tmpdir): base = SkyCoord("16h52m42.2s -38d37m12s") plot_path = tmpdir.join('dither_test.png') positions = dither.get_dither_positions(base_position=base, n_positions=12, pattern=dither.dice9, pattern_offset=30 * u.arcminute, plot=plot_path.strpath) assert plot_path.check()
def test_random(): base = SkyCoord("16h52m42.2s -38d37m12s") positions = dither.get_dither_positions(base_position=base, n_positions=12, random_offset=30 * u.arcsecond) assert isinstance(positions, SkyCoord) assert len(positions) == 12 assert base.spherical_offsets_to(positions[0])[0].radian == pytest.approx(Angle(0 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian) assert base.spherical_offsets_to(positions[0])[1].radian == pytest.approx(Angle(0 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian) assert base.spherical_offsets_to(positions[1])[0].radian == pytest.approx(Angle(0 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian) assert base.spherical_offsets_to(positions[1])[1].radian == pytest.approx(Angle(0 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian)
def test_dice9_random(): base = SkyCoord("16h52m42.2s -38d37m12s") positions = dither.get_dither_positions(base_position=base, n_positions=12, pattern=dither.dice9, pattern_offset=30 * u.arcminute, random_offset=30 * u.arcsecond) assert isinstance(positions, SkyCoord) assert len(positions) == 12 # postion 0 should be the base position assert positions[0].separation(base) < Angle(30 * 2**0.5 * u.arcsecond) # Position 1 should be 30 arcminute offset from base, in declination direction only assert base.spherical_offsets_to(positions[1])[0].radian == pytest.approx(Angle(0 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian) assert base.spherical_offsets_to(positions[1])[1].radian == pytest.approx(Angle(0.5 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian) # Position 3 should be 30 arcminute offset from base in RA only. assert base.spherical_offsets_to(positions[3])[0].radian == pytest.approx(Angle(0.5 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian) assert base.spherical_offsets_to(positions[3])[1].radian == pytest.approx(Angle(0 * u.degree).radian, abs=Angle(30 * u.arcsecond).radian)
def get_target_list(target_name, imagers, primary_imager, base_position, exposure_parameters, dither_parameters={'pattern': dither.dice9, 'pattern_offset': 30 * u.arcminute, 'random_offset': 3 * u.arcminute}, priority=100): """ Generates a list of dictionaries containing the details for a dithered, HDR sequence of exposures. Args: target_name (str): name of the target objects imagers (dictionary): dictionary of `gungala.imager.Imager` objects, as returned from `gunagala.imager.create_imagers()` primary_imager: name of the Imager object from imagers that should be used to calculate the exposure times. base_position (SkyCoord or compatible): base position for the dither pattern, either a SkyCoord or an object that can be converted to one by the SkyCoord constructor (e.g. string). exposure_parameters (dict): dictionary of keyword parameters to pass to `Imager.exp_time_sequence()`. See that method's docstring for details of all the accepted parameters. dither_parameters (dict): dictionary of keyword parameters to pass to `dither.get_dither_positions()``. See that function's docstring for details of all the accepted parameters. priority (optional, default 100): scheduler priority to assign to the exposures. Returns: list: list of dictionaries, each containing the details for an individual exposure. """ try: imager = imagers[primary_imager] except KeyError: raise ValueError( "Could not find imager '{}' in imagers dictionary!".format(primary_imager)) if not isinstance(base_position, SkyCoord): try: base_position = SkyCoord(base_position) except ValueError: raise ValueError( "Base position '{}' could not be converted to a SkyCoord object!", base_position) explist = imager.exp_time_sequence(**exposure_parameters) target_list = [] position_list = dither.get_dither_positions(base_position=base_position, n_positions=len(explist), **dither_parameters) for i in range(0, len(explist)): target = {} if base_position.obstime is not None: target['epoch'] = base_position.obstime if base_position.equinox is not None: target['equinox'] = base_position.equinox target['frame'] = base_position.frame.name target['name'] = target_name target['position'] = position_list[i].to_string('hmsdms') target['priority'] = priority target['exp_time'] = explist[i].value, target_list.append(target) return target_list