Example #1
0
def mean_to_apparent(target, tdb):
    '''Given a target and TDB, return an apparent (RA, Dec) tuple.
       Thin wrapper for SLA_MAP.
    '''

    # Complain if the minimum target fields aren't present
    if not target.get('ra'):
        raise IncompleteTargetError("Missing RA in target definition")

    if not target.get('dec'):
        raise IncompleteTargetError("Missing Declination in target definition")

    target = make_ra_dec_target(
        target['ra'],
        target['dec'],
        ra_proper_motion=target.get('ra_proper_motion'),
        dec_proper_motion=target.get('dec_proper_motion'),
        parallax=target.get('parallax'),
        rad_vel=target.get('rad_vel'),
        epoch=target.get('epoch'))

    (ra_app_rads, dec_app_rads) = sla.sla_map(
        target['ra'].in_radians(), target['dec'].in_radians(),
        target['ra_proper_motion'].in_radians_per_year(),
        target['dec_proper_motion'].in_radians_per_year(), target['parallax'],
        target['rad_vel'], target['epoch'], tdb)

    ra_apparent = Angle(radians=ra_app_rads)
    dec_apparent = Angle(radians=dec_app_rads)

    return (ra_apparent, dec_apparent)
    def setup(self):

        # Target
        # Note: Aladin units are mas/yr...
        self.canopus = {
            'ra': RightAscension('06 23 57.11'),
            'dec': Declination('-52 40 03.5'),
            #'ra_proper_motion'  : ProperMotion(RightAscension('00 00 00.01999')),
            #'dec_proper_motion' : ProperMotion(Declination('00 00 00.02367')),
            'ra_proper_motion': ProperMotion(RightAscension('00 00 00.0')),
            'dec_proper_motion': ProperMotion(Declination('00 00 00.0')),
            #'parallax'          : 0.01043,   # Units: arcsec
            'parallax': 0.0,  # Units: arcsec
            #'rad_vel'           : 20.5,      # Units: km/s (-ve approaches)
            'rad_vel': 0.0,  # Units: km/s (-ve approaches)
            'epoch': 2000,
        }

        # Site (East +ve longitude)
        self.siding_spring = {
            'latitude': Angle(degrees=-31.273),
            'longitude': Angle(degrees=149.070593)
        }

        # Date
        self.date = datetime(year=2010, month=3, day=12)
    def test_read_neocp_orbit4(self):

        # Element dictionary produced by TAL's code from NEOCP orbit file, migrated to
        # rise_set format.
        # This test tests very short orbits from find_orb with an arc length in
        # minutes
        expected = {
                     'name'           : 'LSCTLF3',
                     'epoch'          : 57109.0,
                     'semi_axis'      : 2.2601939,
                     'mean_anomaly'   : Angle(degrees= 23.58746),
                     'arg_perihelion' : Angle(degrees= 75.79622),
                     'long_node'      : Angle(degrees= 69.92181),
                     'inclination'    : Angle(degrees=  9.43941),
                     'eccentricity'   : 0.3369232,
                     'MDM'            : Angle(degrees=0.29005846),
                     'H'              : 18.90,
                     'G'              : 0.15,
                     'n_obs'          : 6,
                     'n_oppos'        : 1,
                     'n_nights'       : old_div(18.8,1440.0),    # 18.8 mins->days
                     'reference'      : 'FO 150328',
                     'residual'       : 0.08,
                     'uncertainty'    : 'U',
                   }

        recieved = read_neocp_orbit('test/LSCTLF3.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
Example #4
0
    def test_get_rise_set_against_lco_rise_set(self):
        facility = FakeFacility()
        sites = facility.get_observing_sites()
        start = datetime(2018, 10, 10)
        end = datetime(2018, 10, 11)

        # Get sunrise/set from rise-set library
        coj = {
            'latitude': Angle(degrees=sites.get('Siding Spring')['latitude']),
            'longitude': Angle(degrees=sites.get('Siding Spring')['longitude'])
        }
        coj_observer = observer_for_site(sites.get('Siding Spring'))
        (transit, control_rise,
         control_set) = calc_sunrise_set(coj, start, 'sunrise')

        # Get rise/set from observations module
        rise_set = get_rise_set(coj_observer, self.sun, start, end)
        rise_delta = timedelta(hours=rise_set[0][0].hour,
                               minutes=rise_set[0][0].minute,
                               seconds=rise_set[0][0].second)
        set_delta = timedelta(hours=rise_set[0][1].hour,
                              minutes=rise_set[0][1].minute,
                              seconds=rise_set[0][1].second)
        self.assertLessEqual(rise_delta - control_rise,
                             abs(timedelta(minutes=5)))
        self.assertLessEqual(set_delta - control_set,
                             abs(timedelta(minutes=5)))
    def test_read_neocp_comet_orbit2(self):

        # Hand-crafted element dictionary from MPC MPES output on 2014-09-26.
        # This test tests periodic comet parsing
        expected = {
                     'name'           : '0299P',
                     'epoch'          : 57000.0,
                     'long_node'      : Angle(degrees=271.6800),
                     'eccentricity'   : 0.282122,
                     'semi_axis'      : None,
                     'mean_anomaly'   : None,
                     'arg_perihelion' : Angle(degrees=323.5091),
                     'inclination'    : Angle(degrees=10.4798),
                     'MDM'            : None,
                     'H'              : 11.5,
                     'G'              : 4.00,
                     'n_obs'          : None,
                     'n_nights'       : None,
                     'type'           : 'MPC_COMET'
                   }

        recieved = read_neocp_orbit('test/Comet_299P.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
    def test_ephemeris_chunk_within_ha_limits(self):
        ha1        = Angle(degrees=3*self.HOURS_TO_DEGREES)
        ha2        = Angle(degrees=3.5*self.HOURS_TO_DEGREES)
        neg_limit  = Angle(degrees=-4.6*self.HOURS_TO_DEGREES)
        pos_limit  = Angle(degrees=4.6*self.HOURS_TO_DEGREES)

        assert_equal(ephemeris_chunk_within_ha_limits(ha1, ha2, neg_limit, pos_limit), True)
    def test_ephemeris_chunk_fully_outside_negative_ha_limit(self):
        ha1        = Angle(degrees=-4.7*self.HOURS_TO_DEGREES)
        ha2        = Angle(degrees=-4.8*self.HOURS_TO_DEGREES)
        neg_limit  = Angle(degrees=-4.6*self.HOURS_TO_DEGREES)
        pos_limit  = Angle(degrees=4.6*self.HOURS_TO_DEGREES)

        assert_equal(ephemeris_chunk_within_ha_limits(ha1, ha2, neg_limit, pos_limit), False)
Example #8
0
def make_minor_planet_target(target_type, epoch, inclination, long_node,
                             arg_perihelion, semi_axis, eccentricity,
                             mean_anomaly):
    """ Creates a rise-set target for a MPC minor planet

    Creates a dictionary rise-set formatted target that must have all the necessary
    coordinates of a MPC formatted minor planet.

    Args:
        target_type (str): The string representation of this target type ('MPC_MINOR_PLANET')
        epoch (float): The epoch of the target ephemerites
        inclination (float): The inclination of the target in degrees
        long_node (float): The longitude of the ascending node in degrees
        arg_perihelion (float): The argument of perihelion in degrees
        semi_axis (float): The semi-axis of the target
        eccentricity (float): The eccentricty of the target
        mean_anomaly (float): The mean anomaly of the target in degrees
    Returns:
        dict: A dictionary of target details to use as input to other rise-set functions
    """
    target = {
        'type': target_type,
        'epoch': epoch,
        'inclination': Angle(degrees=inclination),
        'long_node': Angle(degrees=long_node),
        'arg_perihelion': Angle(degrees=arg_perihelion),
        'semi_axis': semi_axis,
        'eccentricity': eccentricity,
        'mean_anomaly': Angle(degrees=mean_anomaly),
    }

    return target
    def test_find_moving_object_up_intervals1(self):
        window = {
                   'start' : datetime(2013, 12, 10),
                   'end'   : datetime(2013, 12, 11)
                 }

        chunksize = timedelta(hours=3)

        expected_intervals = [
                                (
                                  datetime(2013, 12, 10, 9),
                                  datetime(2013, 12, 10, 12)
                                ),
                                (
                                  datetime(2013, 12, 10, 12),
                                  datetime(2013, 12, 10, 15)
                                )
                             ]
        expected_altitudes = [
                               Angle(degrees=42.7537),
                               Angle(degrees=74.9902)
                             ]

        received_ints, received_alts = find_moving_object_up_intervals(window,
                                                               self.elements,
                                                               self.cpt, chunksize)

        assert_equal(len(expected_intervals), len(received_ints))
        assert_equal(len(expected_altitudes), len(received_alts))

        for e, r in zip(expected_intervals, received_ints):
            assert_equal(e, r)

        for e, r in zip(expected_altitudes, received_alts):
            assert_almost_equal(e.in_degrees(), r.in_degrees(), places=3)
    def test_read_neocp_comet_orbit1(self):

        # Hand-crafted element dictionary from MPC MPES output on 2014-09-26.
        # This test tests long-period comet parsing
        expected = {
                     'name'           : 'CK13A010',
                     'epoch'          : 57000.0,
                     'long_node'      : Angle(degrees=300.9764),
                     'eccentricity'   : 1.000434,
                     'semi_axis'      : None,
                     'mean_anomaly'   : None,
                     'arg_perihelion' : Angle(degrees=2.4226),
                     'inclination'    :  Angle(degrees=129.0428),
                     'MDM'            :  None,
                     'H'              : 8.2,
                     'G'              : 2.4,
                     'n_obs'          : None,
                     'n_nights'       : None,
                     'type'           : 'MPC_COMET'
                   }

        recieved = read_neocp_orbit('test/Comet_SidingSpring.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
Example #11
0
def apparent_planet_pos(planet_name, tdb, site):
    '''Return the topocentric apparent position (ra, dec) tuple of a planet at
       a particular time, from a particular site.
       Thin wrapper for SLA_RDPLAN.
    '''

    latitude = site['latitude']
    longitude = site['longitude']

    # TODO: Raise an error if an invalid body is provided.

    planet = dict(mercury=1,
                  venus=2,
                  moon=3,
                  mars=4,
                  jupiter=5,
                  saturn=6,
                  uranus=7,
                  neptune=8,
                  pluto=9,
                  sun=0)

    (app_ra_rads, app_dec_rads,
     diameter_rads) = sla.sla_rdplan(tdb, planet[planet_name],
                                     longitude.in_radians(),
                                     latitude.in_radians())

    app_ra = Angle(radians=app_ra_rads)
    app_dec = Angle(radians=app_dec_rads)
    diameter = Angle(radians=diameter_rads)

    return (app_ra, app_dec, diameter)
    def test_read_neocp_orbit5(self):

        # Element dictionary produced by TAL's code from NEOCP orbit file, migrated to
        # rise_set format.
        # This test tests very short orbits from find_orb with an arc length in
        # hours
        expected = {
                     'name'           : 'LSCTLF3',
                     'epoch'          : 57109.0,
                     'mean_anomaly'   : Angle(degrees= 21.73763),
                     'arg_perihelion' : Angle(degrees= 80.02788),
                     'long_node'      : Angle(degrees= 64.35739),
                     'inclination'    : Angle(degrees= 12.17788),
                     'eccentricity'   : 0.3895454,
                     'MDM'            : Angle(degrees=0.21752314),
                     'semi_axis'      : 2.7382037,
                     'H'              : 18.23,
                     'G'              : 0.15,
                     'n_obs'          : 10,
                     'n_oppos'        : 1,
                     'n_nights'       : old_div(13.0,24.0),    # 13.0 hrs->days
                     'reference'      : 'FO 150328',
                     'residual'       : 0.09,
                     'uncertainty'    : 'U',
                   }

        recieved = read_neocp_orbit('test/LSCTLF3_V2.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
    def test_read_neocp_orbit7(self):

        # Element dictionary produced by TAL's code from NEOCP orbit file, migrated to
        # rise_set format.
        # This test tests NEOCP orbits without an uncertainty.
        expected = {
                     'name'           : 'N007rdx',
                     'epoch'          : 57120.0,
                     'mean_anomaly'   : Angle(degrees=119.11683),
                     'arg_perihelion' : Angle(degrees= 75.91136),
                     'long_node'      : Angle(degrees=351.90874),
                     'inclination'    : Angle(degrees=  3.64505),
                     'eccentricity'   : 0.1054741,
                     'MDM'            : Angle(degrees=1.07358714),
                     'semi_axis'      : 0.9445925,
                     'H'              : 21.8,
                     'G'              : 0.15,
                     'n_obs'          : 5,
                     'n_oppos'        : 1,
                     'n_nights'       : 0,
                     'uncertainty'    : 'U',   # No value, assume default
                     'reference'      : '',
                   }

        recieved = read_neocp_orbit('test/N007rdx.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
    def test_read_neocp_orbit3(self):

        # Element dictionary produced by TAL's code from NEOCP orbit file, migrated to
        # rise_set format.
        # This test tests multi-opposition orbits
        expected = {
                     'name'           : '00001',
                     'epoch'          : 57200.0,
                     'long_node'      : Angle(degrees=80.3272),
                     'eccentricity'   : 0.0757825,
                     'semi_axis'      : 2.7679724,
                     'mean_anomaly'   : Angle(degrees=138.66222),
                     'arg_perihelion' : Angle(degrees= 72.65410),
                     'inclination'    : Angle(degrees= 10.59230),
                     'MDM'            : Angle(degrees=0.21402349),
                     'H'              :  3.34,
                     'G'              : 0.12,
                     'n_obs'          : 6541,
                     'n_oppos'        : 107,
                     'n_nights'       : '1802-2014',
                     'reference'      : 'MPO328644',
                     'uncertainty'    : '0',
                   }

        recieved = read_neocp_orbit('test/00001_Ceres.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
Example #15
0
    def __init__(self,
                 site,
                 start_date,
                 end_date,
                 horizon=0,
                 twilight='sunrise',
                 ha_limit_neg=-4.9,
                 ha_limit_pos=4.9,
                 zenith_blind_spot=0):
        self.site = site
        self.start_date = start_date
        self.end_date = end_date
        self.horizon = Angle(degrees=horizon)
        self.twilight = twilight
        self.zenith_blind_spot = Angle(degrees=zenith_blind_spot)

        if ha_limit_pos > 12.0 or ha_limit_pos < 0.0:
            msg = "Positive hour angle limit must fall between 0 and 12 hours"
            raise InvalidHourAngleLimit(msg)

        if ha_limit_neg < -12.0 or ha_limit_neg > 0.0:
            msg = "Negative hour angle limit must fall between -12 and 0 hours"
            raise InvalidHourAngleLimit(msg)

        self.ha_limit_neg = ha_limit_neg
        self.ha_limit_pos = ha_limit_pos

        self.dark_intervals = []
        self.moon_dark_intervals = []
    def test_read_neocp_orbit2(self):

        # Element dictionary produced by TAL's code from NEOCP orbit file, migrated to
        # rise_set format.
        expected = {
                     'name'           : 'K13TB7L',
                     'epoch'          : 56600.0,
                     'long_node'      : Angle(degrees=3.36296),
                     'eccentricity'   : 0.6898696,
                     'semi_axis'      : 3.6038493,
                     'mean_anomaly'   : Angle(degrees=344.69702),
                     'arg_perihelion' : Angle(degrees=112.20127),
                     'inclination'    : Angle(degrees=9.36592),
                     'MDM'            : Angle(degrees=0.14406356),
                     'H'              : 17.7,
                     'G'              : 0.15,
                     'n_obs'          : 146,
                     'n_oppos'        : 1,
                     'n_nights'       : 67,
                     'reference'      : 'E2013-X58',
                     'uncertainty'    : '3',
                   }

        recieved = read_neocp_orbit('test/2013TL117.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
    def test_read_neocp_orbit1(self):

        # Element dictionary produced by TAL's code from NEOCP orbit file, migrated to
        # rise_set format.
        expected = {
                     'name': 'P109rXK',
                     'epoch': 56620.0,
                     'long_node':  Angle(degrees=224.42273),
                     'eccentricity': 0.5131088,
                     'semi_axis': 2.0773493,
                     'mean_anomaly':  Angle(degrees=322.22271),
                     'arg_perihelion': Angle(degrees=307.96804),
                     'inclination':  Angle(degrees=13.72592),
                     'MDM':  Angle(degrees=0.3291848),
                     'H': 17.5,
                     'G': 0.15,
                     'n_obs': 4,
                     'n_oppos' : 1,
                     'n_nights': 0,
                   }

        recieved = read_neocp_orbit('test/P109rXK.neocp')

        for e in list(expected.keys()):
            assert_equal(expected[e], recieved[e])
Example #18
0
def make_comet_target(target_type, epoch, epochofperih, inclination, long_node,
                      arg_perihelion, perihdist, eccentricity):
    """ Creates a rise-set target for a MPC comet

    Creates a dictionary rise-set formatted target that must have all the necessary
    coordinates of a MPC formatted comet.

    Args:
        target_type (str): The string representation of this target type ('MPC_COMET')
        epoch (float): The epoch of the target ephemerites
        epochofperih (float): The epoch of perihelion
        inclination (float): The inclination of the target in degrees
        long_node (float): The longitude of the ascending node in degrees
        arg_perihelion (float): The argument of perihelion in degrees
        perihdist (float): The perihelion distance of the target
        eccentricity (float): The eccentricty of the target
    Returns:
        dict: A dictionary of target details to use as input to other rise-set functions
    """
    target = {
        'type': target_type,
        'epoch': epoch,
        'epochofperih': epochofperih,
        'inclination': Angle(degrees=inclination),
        'long_node': Angle(degrees=long_node),
        'arg_perihelion': Angle(degrees=arg_perihelion),
        'perihdist': perihdist,
        'eccentricity': eccentricity,
    }

    return target
    def test_calc_local_hour_angle_normalises_positive_overrun(self):
        ra_app = Angle(degrees=108.75)
        coj_longitude = Angle(degrees=149.070593)
        date = datetime(2014, 1, 12, 14)

        hour_angle = calc_local_hour_angle(ra_app, coj_longitude, date)

        assert_almost_equal(hour_angle.in_degrees(), 2.3088, places=4)
    def test_calc_local_hour_angle_normalises_negative_overrun(self):
        ra_app = Angle(degrees=288.75)
        elp_longitude = Angle(degrees=-104.015194444)
        date = datetime(2014, 7, 18, 7)

        hour_angle = calc_local_hour_angle(ra_app, elp_longitude, date)

        assert_almost_equal(hour_angle.in_degrees(), 8.2509, places=4)
Example #21
0
def get_rise_set_site(site_detail):
    return {
        'latitude': Angle(degrees=site_detail['latitude']),
        'longitude': Angle(degrees=site_detail['longitude']),
        'horizon': Angle(degrees=site_detail['horizon']),
        'ha_limit_neg': Angle(degrees=site_detail['ha_limit_neg'] * HOURS_PER_DEGREES),
        'ha_limit_pos': Angle(degrees=site_detail['ha_limit_pos'] * HOURS_PER_DEGREES)
    }
    def test_calc_local_hour_angle(self):
        ra_app = Angle(degrees=30)
        elp_longitude = Angle(degrees=-104.015194444)
        date = datetime(2013, 12, 10)

        hour_angle = calc_local_hour_angle(ra_app, elp_longitude, date)

        assert_almost_equal(hour_angle.in_degrees(),
                            -55.128564469690645,
                            places=13)
Example #23
0
def telescope_to_rise_set_telescope(telescope):
    """Convert scheduler Telescope to rise_set telescope dict."""
    # TODO: Move scheduler Telescope code to rise_set.
    HOURS_TO_DEGREES = 15
    return {
        'latitude': Angle(degrees=telescope['latitude']),
        'longitude': Angle(degrees=telescope['longitude']),
        'ha_limit_neg': Angle(degrees=telescope['ha_limit_neg'] * HOURS_TO_DEGREES),
        'ha_limit_pos': Angle(degrees=telescope['ha_limit_pos'] * HOURS_TO_DEGREES),
        'zenith_blind_spot': Angle(degrees=telescope['zenith_blind_spot'] * HOURS_TO_DEGREES)
    }
Example #24
0
def calc_sunrise_set(site, date, twilight):
    '''Return a tuple (transit, rise, set) of timedelta objects, describing the
       time offset for each event from the start of the provided date.
    '''
    sun_std_alt = {
        'sunrise': Angle(degrees=-5 / 6),
        'sunset': Angle(degrees=-5 / 6),
        'civil': Angle(degrees=-6),
        'nautical': Angle(degrees=-12),
        'astronomical': Angle(degrees=-18)
    }
    return calc_planet_rise_set(site, date, sun_std_alt[twilight], 'sun')
    def setup(self):
        self.lsc = {
            'name': '1m0a.domb.lsc',
            'latitude': Angle(degrees=-30.1673472222),
            'longitude': Angle(degrees=-70.8046722222),
        }

        self.elp = {
            'name': '1m0a.doma.elp',
            'latitude': Angle(degrees=30.6801),
            'longitude': Angle(degrees=-104.015194444),
        }
Example #26
0
def apparent_to_altzd(ra, dec, aop_params):
    '''
        Perform apparent->observed place transformation on a targets apparent ra and dec, given aop_params which
        are generated from slalibs sla_aoppa call.
    :param ra: apparent ra
    :param dec: apparent dec
    :param aop_params: slalibs aop params structure
    :return: azimuth and zenith angles
    '''
    (obs_az, obs_zd, obs_ha, obs_dec,
     obs_ra) = sla.sla_aopqk(ra.in_radians(), dec.in_radians(), aop_params)

    return Angle(radians=obs_az), Angle(radians=obs_zd)
Example #27
0
    def add_site(self, site_dict):
        lat_long = (site_dict['latitude'], site_dict['longitude'])
        HOURS_TO_DEGREES = 15.0

        if lat_long not in self.site_lat_longs:
            self.site_lat_longs.append(lat_long)
            site_dict['latitude']         = Angle(degrees=site_dict['latitude'])
            site_dict['longitude']        = Angle(degrees=site_dict['longitude'])
            site_dict['horizon']          = Angle(degrees=site_dict['horizon'])
            site_dict['ha_limit_neg']     = Angle(degrees=site_dict['ha_limit_neg'] * HOURS_TO_DEGREES)
            site_dict['ha_limit_pos']     = Angle(degrees=site_dict['ha_limit_pos'] * HOURS_TO_DEGREES)
            self.sites[site_dict['name']] = site_dict

        return
Example #28
0
    def __init__(self, time=None, degrees=None, radians=None, units='time'):

        angle_degrees = time
        angle_radians = radians
        angle_units = units

        if degrees != None:
            angle_degrees = degrees
            angle_units = 'arc'

        Angle.__init__(self, angle_degrees, angle_radians, angle_units)

        # Check input
        self.validate_ra()
    def setup(self):
        self.site = {
            'name': 'test',
            'latitude': Angle(degrees=-30.0),
            'longitude': Angle(degrees=0.0)
        }

        self.h_0 = MOON_REFRACTION

        # 5 arcsecond tolerance
        self.tolerance = 5.0 / 3600.0

        # rise/set/transit time tolerance in seconds
        self.time_tolerance = 3.0 * 60.0
    def test_calc_ephemerides(self):
        window = {
                   'start' : datetime(2013, 12, 10),
                   'end'   : datetime(2013, 12, 11)
                 }

        chunksize = timedelta(hours=6)

        expected = [
                     {
                       'ra_app'  : Angle(degrees=285.22681),
                       'dec_app' : Angle(degrees=-18.16350),
                       'start'   : window['start'],
                       'end'     : window['start'] + (1 * chunksize),
                     },
                     {
                       'ra_app'  : Angle(degrees=285.35677),
                       'dec_app' : Angle(degrees=-18.15597),
                       'start'   : window['start'] + (1 * chunksize),
                       'end'     : window['start'] + (2 * chunksize),
                     },
                     {
                       'ra_app'  : Angle(degrees=285.48538),
                       'dec_app' : Angle(degrees=-18.14841),
                       'start'   : window['start'] + (2 * chunksize),
                       'end'     : window['start'] + (3 * chunksize),
                     },
                     {
                       'ra_app'  : Angle(degrees=285.61369),
                       'dec_app' : Angle(degrees=-18.14033),
                       'start'   : window['start'] + (3 * chunksize),
                       'end'     : window['start'] + (4 * chunksize),
                     },
                     {
                       'ra_app'  : Angle(degrees=285.74337),
                       'dec_app' : Angle(degrees=-18.13206),
                       'start'   : window['start'] + (4 * chunksize),
                       'end'     : window['start'] + (4 * chunksize),
                     },
                   ]

        received = calc_ephemerides(window, self.elements, self.cpt, chunksize)

        for e, r in zip(expected, received):
            assert_almost_equal(e['ra_app'].in_degrees(), r['ra_app'].in_degrees(), places=3)
            assert_almost_equal(e['dec_app'].in_degrees(), r['dec_app'].in_degrees(), places=4)
            assert_equal(e['start'], r['start'])
            assert_equal(e['end'], r['end'])