Exemplo n.º 1
0
def do_calibration_40b(i, obstime_utc, telescope_position, csvfile, total_wait,
                       next_cal, mins_per_beam):

    calib_sun_dist = 30.

    current_lst = Time(obstime_utc).sidereal_time('apparent', westerbork().lon)
    # Consider HA limits for shadowing:
    #     https://old.astron.nl/radio-observatory/astronomers/wsrt-guide-observations/3-telescope-parameters-and-array-configuration
    # Note ha_limit[1:2] depend on length of calibration!
    syswait = 2.0  # minutes
    obstime = (mins_per_beam + syswait) * 40. - syswait  # minutes
    sun_position = get_sun(Time(obstime_utc, scale='utc'))
    if (i == 4):
        next_cal = 'flux'
        print(next_cal)
    if next_cal == 'flux':
        calibrators = flux_cal
        names = flux_names
        type_cal = 'Flux'
        ha_limit = [-5.0, 5.0 - obstime / 60.,
                    0.4]  # Entry 2 is hardcoded for 5 min per beam
    if next_cal == 'pol':
        calibrators = pol_cal
        names = pol_names
        type_cal = 'Polarization'
        ha_limit = [-3.3, 3.3 - obstime / 60.,
                    -1.0]  # Entry 2 is hardcoded for 5 min per beam
    is_cal_up = np.array([
        (current_lst.hour - calibrators[0].ra.hour > ha_limit[0])
        and (current_lst.hour - calibrators[0].ra.hour < ha_limit[1]),
        (current_lst.hour - calibrators[1].ra.hour > ha_limit[0])
        and (current_lst.hour - calibrators[1].ra.hour < ha_limit[2])
    ])
    is_sundist_okay = np.array([
        sun_position.separation(calibrators[0]).value > calib_sun_dist,
        sun_position.separation(calibrators[1]).value > calib_sun_dist
    ])
    calib_wait = 0
    new_obstime_utc = obstime_utc

    # Wait for calibrator to be at least an hour above the observing horizon, or not shadowed.
    while not np.any(is_cal_up * is_sundist_okay
                     ):  # and (calib_wait < 6. * 60.): # and (not is3c286):
        calib_wait += dowait
        new_obstime_utc = wait_for_rise(new_obstime_utc, waittime=dowait)
        new_lst = Time(new_obstime_utc).sidereal_time('apparent',
                                                      westerbork().lon)
        is_cal_up = [(new_lst.hour - calibrators[0].ra.hour > ha_limit[0])
                     and (new_lst.hour - calibrators[0].ra.hour < ha_limit[1]),
                     (new_lst.hour - calibrators[1].ra.hour > ha_limit[0])
                     and (new_lst.hour - calibrators[1].ra.hour < ha_limit[2])]
    n = np.where(is_cal_up)[0][0]
    ##### EDITABLE: Can change the number of hours the program will wait for a calibrator #####
    if calib_wait != 0 and calib_wait < 4.0 * 60:
        total_wait += calib_wait
        n = np.where(is_cal_up)[0][0]
        print("\tCalibrator not up, waiting {} minutes until LST: {}.".format(
            calib_wait, str(new_lst)))
    # The commented part is hopefully obsolete with the new calibrator.py and observing strategy, but there's still a bad starting point in the sky
    # elif calib_wait >= 4.0 * 60:
    elif calib_wait >= 8.0 * 60:
        after_cal = obstime_utc - datetime.timedelta(minutes=syswait)
        new_telescope_position = telescope_position
        i -= 1
        # If can't do any pol at beginning, first must be a flux cal
        # (if statement untested; trying to fix skipping pol cal when this happens in the middle!):
        if i == 1:
            next_cal = 'flux'
        print(
            "Must wait {} hours for calibrator to rise.  Instead, go directly to target."
            .format(calib_wait / 60.))
        print(
            "\tIf this appears anywhere other than beginning of scheduling block, probably need to expanding "
            "options in pointing file.")
        # break
        return i, after_cal, new_telescope_position, total_wait, next_cal

    slew_seconds = calc_slewtime(
        [telescope_position.ra.radian, telescope_position.dec.radian],
        [calibrators[n].ra.radian, calibrators[n].dec.radian])
    if slew_seconds < calib_wait * 60.:
        new_obstime_utc = obstime_utc + datetime.timedelta(minutes=calib_wait)
    else:
        new_obstime_utc = obstime_utc + datetime.timedelta(
            seconds=slew_seconds)

    # Calculate appropriate observe time for the calibrator and observe it.
    obstime = (
        mins_per_beam + syswait
    ) * 40. - syswait  # <mins_per_beam> minutes per beam, 2 min wait
    if n == 1:
        obstime = (
            5.0 + syswait
        ) * 40. - syswait  # force 5 minutes per beam, 2 min wait on calibs with natural gap before target
    after_cal = observe_calibrator(new_obstime_utc, obstime=obstime)
    if i == 1:
        write_to_csv(csvfile, 'imaging_start', calibrators[n],
                     new_obstime_utc - datetime.timedelta(minutes=3.0),
                     new_obstime_utc - datetime.timedelta(minutes=2.0))
    write_to_csv(csvfile, names[n], calibrators[n], new_obstime_utc, after_cal)

    print("Scan {} observed {} calibrator {}.".format(i, type_cal, names[n]))
    check_sun = sun_position.separation(calibrators[n])
    if check_sun.value < calib_sun_dist:
        print("\tWARNING: {} is THIS close to Sun: {:5.2f}".format(
            names[n], check_sun))
    new_telescope_position = calibrators[n]

    # Set up for next calibrator
    if next_cal == 'flux':
        next_cal = 'pol'
    else:
        next_cal = 'flux'

    return i, after_cal, new_telescope_position, total_wait, next_cal
Exemplo n.º 2
0
def do_target_observation(i, obstime_utc, telescope_position, csvfile,
                          total_wait):  #, closest_field):
    # Get objects that are close to current observing horizon:
    current_lst = Time(obstime_utc).sidereal_time('apparent', westerbork().lon)

    proposed_ra = (current_lst + Longitude('6h')).wrap_at(360 * u.deg)
    test_slew_seconds = calc_slewtime(
        [telescope_position.ra.radian, telescope_position.dec.radian],
        [proposed_ra.radian, telescope_position.dec.radian])

    avail_fields = apertif_fields[apertif_fields['weights'] > 0]
    availability = SkyCoord(
        np.array(avail_fields['hmsdms']
                 )).ra.hour - proposed_ra.hour - test_slew_seconds / 3600.
    availability[availability < -12.] += 24.

    sun_position = get_sun(Time(obstime_utc, scale='utc'))
    sun_okay = np.array(
        sun_position.separation(SkyCoord(avail_fields['hmsdms'])).value)

    targ_wait = 0.  # minutes
    ##### EDITABLE: Will control the maximum wait time for a target before it gives up and looks for a calibrator #####
    # wait_limit = 5.0  # hours
    wait_limit = 10.0  # hours

    new_obstime_utc = obstime_utc
    # First check what is *already* up.  If nothing, then wait for something to rise.
    ##### If target is passing it's HA limit, adjust availability numbers (especially the second one) #####
    while not np.any((availability < -0.02) & (availability > -0.40)
                     & (sun_okay > args.sun_distance)):
        targ_wait += dowait
        new_obstime_utc = wait_for_rise(new_obstime_utc, waittime=dowait)
        new_lst = Time(new_obstime_utc).sidereal_time('apparent',
                                                      westerbork().lon)
        proposed_ra = (new_lst + Longitude('6h')).wrap_at(360 * u.deg)
        availability = SkyCoord(np.array(
            avail_fields['hmsdms'])).ra.hour - proposed_ra.hour
        availability[availability < -12.] += 24.
        # print(availability, sun_okay > args.sun_distance, sun_okay)
    if (targ_wait != 0.) and (targ_wait <= wait_limit * 60.):
        total_wait += targ_wait
        print(
            "\tTarget not up (or sun issues), waiting {} minutes until LST: {}"
            .format(targ_wait, str(new_lst)))

    if targ_wait <= wait_limit * 60.:
        # Choose M101 field first if available or within a 1 hour wait AND (before this function) if users had requested it in args.repeat_m101
        if 'M1403+5324' in avail_fields[(availability < -0.02)
                                        & (availability > -0.40)]['name']:
            first_field = avail_fields[avail_fields['name'] == 'M1403+5324'][0]
            print(
                "*** M1403+5324 OBSERVED!  WAIT A MONTH TO SCHEDULE AGAIN! ***"
            )
        elif 'M1403+5324' in avail_fields[(availability < 1.00)
                                          & (availability > -0.02)]['name']:
            m101_field = avail_fields[avail_fields['name'] == 'M1403+5324'][0]
            m101_availability = SkyCoord(
                m101_field['hmsdms']).ra.hour - proposed_ra.hour
            while not (m101_availability < -0.02) & (m101_availability >
                                                     -0.40):
                targ_wait += dowait
                new_obstime_utc = wait_for_rise(new_obstime_utc,
                                                waittime=dowait)
                new_lst = Time(new_obstime_utc).sidereal_time(
                    'apparent',
                    westerbork().lon)
                proposed_ra = (new_lst + Longitude('6h')).wrap_at(360 * u.deg)
                m101_availability = SkyCoord(
                    m101_field['hmsdms']).ra.hour - proposed_ra.hour
                # m101_availability[m101_availability < -12] += 24
            first_field = m101_field
            print(
                "*** M1403+5324 OBSERVED!  WAIT A MONTH TO SCHEDULE AGAIN! ***"
            )
        else:
            first_field = avail_fields[(availability < -0.02)
                                       & (availability > -0.40) &
                                       (sun_okay > args.sun_distance)][0]
            check_sun = sun_position.separation(SkyCoord(
                first_field['hmsdms']))
            if check_sun.value < 50.:
                print("\tField is THIS close to Sun: {}".format(check_sun))

        # NOTE SLEW TIME IS CALCULATED TO THE *OBSERVING* HORIZON, NOT TO THE NEW RA!
        # TELESCOPE SHOULD MOVE TO HORIZON AND WAIT!!!
        slew_seconds = calc_slewtime(
            [telescope_position.ra.radian, telescope_position.dec.radian], [
                SkyCoord(first_field['hmsdms']).ra.radian,
                SkyCoord(first_field['hmsdms']).dec.radian
            ])
        if slew_seconds < targ_wait * 60.:
            new_obstime_utc = obstime_utc + datetime.timedelta(
                minutes=targ_wait)
        else:
            new_obstime_utc = obstime_utc + datetime.timedelta(
                seconds=slew_seconds)
        after_target = observe_target(apertif_fields,
                                      new_obstime_utc,
                                      first_field['name'],
                                      obstime=11.5)
        write_to_csv(csvfile, first_field['name'],
                     SkyCoord(first_field['hmsdms']), new_obstime_utc,
                     after_target)
        print("Scan {} observed {}.".format(i, first_field['hmsdms']))
        return i, after_target, SkyCoord(first_field['hmsdms']), total_wait
    else:
        print("\tNo target for {} hours. Go to a calibrator instead.".format(
            targ_wait / 60.))
        i -= 1
        return i, obstime_utc, telescope_position, total_wait
Exemplo n.º 3
0
def do_calibration(i, obstime_utc, telescope_position, csvfile, total_wait):
    current_lst = Time(obstime_utc).sidereal_time('apparent', westerbork().lon)
    is3c147 = np.abs(current_lst.hour - flux_cal[0].ra.hour < 5.0)
    is_ctd93 = np.abs(current_lst.hour - pol_cal[2].ra.hour < 5.0)

    calib_wait = 0
    # Wait for calibrator to be at least an hour above the horizon.
    while (not is3c147) and (not is_ctd93):
        calib_wait += dowait
        total_wait += dowait
        new_obstime_utc = wait_for_rise(obstime_utc, waittime=dowait)
        obstime_utc = new_obstime_utc
        current_lst = Time(obstime_utc).sidereal_time('apparent',
                                                      westerbork().lon)
        is3c147 = np.abs(current_lst.hour - flux_cal[0].ra.hour) < 5.0
        is_ctd93 = np.abs(current_lst.hour - pol_cal[2].ra.hour) < 5.0
    if calib_wait != 0:
        print("\tCalibrator not up, waiting {} minutes until LST: {}.".format(
            calib_wait, str(current_lst)))

    # Observe the calibrator(s) that is (are) up:
    if is3c147:
        slew_seconds = calc_slewtime(
            [telescope_position.ra.radian, telescope_position.dec.radian],
            [flux_cal[0].ra.radian, flux_cal[0].dec.radian])
        new_obstime_utc = obstime_utc + datetime.timedelta(
            seconds=slew_seconds)
        after_3c147 = observe_calibrator(new_obstime_utc, obstime=15)
        write_to_csv(csvfile, flux_names[0], flux_cal[0], new_obstime_utc,
                     after_3c147)
        print("Scan {} observed {}.".format(i, flux_names[0]))

        sun_position = get_sun(Time(new_obstime_utc, scale='utc'))
        check_sun = sun_position.separation(flux_cal[0])
        if check_sun.value < args.sun_distance:
            print("\tWARNING: {} is THIS close to Sun: {:5.2f}".format(
                flux_names[0], check_sun))

        i += 1
        slew_seconds = calc_slewtime(
            [flux_cal[0].ra.radian, flux_cal[0].dec.radian],
            [pol_cal[0].ra.radian, pol_cal[0].dec.radian])
        new_obstime_utc = after_3c147 + datetime.timedelta(
            seconds=slew_seconds)
        after_3c138 = observe_calibrator(new_obstime_utc, obstime=15)
        write_to_csv(csvfile, pol_names[0], pol_cal[0], new_obstime_utc,
                     after_3c138)
        print("Scan {} observed {}.".format(i, pol_names[0]))

        check_sun = sun_position.separation(pol_cal[0])
        if check_sun.value < args.sun_distance:
            print("\tWARNING: {} is THIS close to Sun: {:5.2f}".format(
                pol_names[0], check_sun))
        return i, after_3c138, pol_cal[0], total_wait

    else:
        slew_seconds = calc_slewtime(
            [telescope_position.ra.radian, telescope_position.dec.radian],
            [pol_cal[2].ra.radian, pol_cal[2].dec.radian])
        new_obstime_utc = obstime_utc + datetime.timedelta(
            seconds=slew_seconds)
        after_ctd93 = observe_calibrator(new_obstime_utc, obstime=15)
        write_to_csv(csvfile, pol_names[2], pol_cal[2], new_obstime_utc,
                     after_ctd93)
        print("Scan {} observed {}.".format(i, pol_names[2]))

        sun_position = get_sun(Time(new_obstime_utc, scale='utc'))
        check_sun = sun_position.separation(pol_cal[2])
        if check_sun.value < args.sun_distance:
            print("\tWARNING: {} is THIS close to Sun: {:5.2f}".format(
                pol_names[2], check_sun))
        return i, after_ctd93, pol_cal[2], total_wait
Exemplo n.º 4
0
def do_target_observation(i, obstime_utc, telescope_position, csvfile,
                          total_wait, closest_field):
    # Get first position or objects that are close to current observing horizon:
    current_lst = Time(obstime_utc).sidereal_time('apparent', westerbork().lon)
    proposed_ra = (current_lst + Longitude('1.5h')).wrap_at(360 * u.deg)

    avail_fields = timing_fields[timing_fields['weights'] > 0]
    if closest_field:
        availability = SkyCoord(
            timing_fields['hmsdms'][closest_field]).ra.hour - proposed_ra.hour
    else:
        availability = SkyCoord(np.array(
            avail_fields['hmsdms'])).ra.hour - proposed_ra.hour
    availability[availability < -12] += 24

    targ_wait = 180  # to make sure ATDB has enough time to start a new observation
    while not np.any((availability < 0.5) & (availability > -0.5)):
        targ_wait += dowait
        total_wait += dowait
        new_obstimeUTC = wait_for_rise(obstime_utc, waittime=dowait)
        obstime_utc = new_obstimeUTC
        current_lst = Time(obstime_utc).sidereal_time('apparent',
                                                      westerbork().lon)
        proposed_ra = (current_lst + Longitude('1.5h')).wrap_at(360 * u.deg)
        if closest_field:
            availability = SkyCoord(timing_fields['hmsdms']
                                    [closest_field]).ra.hour - proposed_ra.hour
        else:
            availability = SkyCoord(np.array(
                avail_fields['hmsdms'])).ra.hour - proposed_ra.hour
        availability[availability < -12] += 24
    if targ_wait != 180:
        print("\tTarget not up, waiting {} minutes until LST: {}".format(
            targ_wait, str(current_lst)))
    sun_position = get_sun(Time(obstime_utc, scale='utc'))
    moon_position = get_moon(Time(obstime_utc, scale='utc'))

    if closest_field:
        first_field = timing_fields[closest_field][0]
        check_sun = sun_position.separation(SkyCoord(first_field['hmsdms']))
        check_moon = moon_position.separation(SkyCoord(first_field['hmsdms']))
        if check_sun.value < args.sun_distance:
            print("\tWARNING: {} is THIS close to Sun: {:5.2f}".format(
                name, check_sun))
        if check_moon.value < 0.5:
            print("\tWARNING: {} is within 0.5 deg of the Moon.".format(name))

    else:
        first_field = random.choice(avail_fields[(availability < 0.5)
                                                 & (availability > -0.5)])
        check_sun = sun_position.separation(SkyCoord(first_field['hmsdms']))
        check_moon = moon_position.separation(SkyCoord(first_field['hmsdms']))
        while (check_sun.value < args.sun_distance) or (check_moon.value <
                                                        0.5):
            print(
                "\tSun or Moon too close to first pick; choose another target field"
            )
            first_field = random.choice(avail_fields[(availability < 0.5)
                                                     & (availability > -0.5)])
            check_sun = sun_position.separation(SkyCoord(
                first_field['hmsdms']))
            check_moon = moon_position.separation(
                SkyCoord(first_field['hmsdms']))

    # NOTE SLEW TIME IS CALCULATED TO THE *OBSERVING* HORIZON, NOT TO THE NEW RA!
    # TELESCOPE SHOULD MOVE TO HORIZON AND WAIT!!!
    slew_seconds = calc_slewtime(
        [telescope_position.ra.radian, telescope_position.dec.radian], [
            SkyCoord(first_field['hmsdms']).ra.radian,
            SkyCoord(first_field['hmsdms']).dec.radian
        ])
    new_obstimeUTC = obstime_utc + datetime.timedelta(
        seconds=slew_seconds) + datetime.timedelta(seconds=targ_wait)
    after_target = observe_target(timing_fields,
                                  new_obstimeUTC,
                                  first_field['name'],
                                  obstime=3)
    write_to_csv(csvfile,
                 first_field['name'],
                 SkyCoord(first_field['hmsdms']),
                 new_obstimeUTC,
                 after_target,
                 pulsar=False)
    print("Scan {} observed {}.".format(i, first_field['hmsdms']))
    return i, after_target, SkyCoord(first_field['hmsdms']), total_wait
Exemplo n.º 5
0
def do_calibration(i, obstime_utc, telescope_position, csvfile, total_wait):
    current_lst = Time(obstime_utc).sidereal_time('apparent', westerbork().lon)
    isB1933 = np.abs(current_lst.hour - psr_cal[0].ra.hour) < 5.0
    isB0531 = np.abs(current_lst.hour - psr_cal[1].ra.hour) < 5.0
    isB0329 = np.abs(current_lst.hour - psr_cal[2].ra.hour) < 5.0
    isB0950 = np.abs(current_lst.hour - psr_cal[3].ra.hour) < 5.0

    calib_wait = 180  # to make sure ATDB has enough time to start a new observation
    # Wait for calibrator to be at least an hour above the horizon.
    while (not isB1933) and (not isB0531) and (not isB0329) and (not isB0950):
        calib_wait += dowait
        total_wait += dowait
        new_obstime_utc = wait_for_rise(obstime_utc, waittime=dowait)
        obstime_utc = new_obstime_utc
        current_lst = Time(obstime_utc).sidereal_time('apparent',
                                                      westerbork().lon)
        isB1933 = np.abs(current_lst.hour - psr_cal[0].ra.hour) < 5.0
        isB0531 = np.abs(current_lst.hour - psr_cal[1].ra.hour) < 5.0
        isB0329 = np.abs(current_lst.hour - psr_cal[2].ra.hour) < 5.0
        isB0950 = np.abs(current_lst.hour - psr_cal[3].ra.hour) < 5.0
    if calib_wait != 180:
        print("\tCalibrator not up, waiting {} minutes until LST: {}.".format(
            calib_wait, str(current_lst)))

    # Observe the calibrator(s) that is (are) up:
    if isB1933:
        name = psr_names[0]
        psr = psr_cal[0]
    elif isB0531:
        name = psr_names[1]
        psr = psr_cal[1]
    elif isB0329:
        name = psr_names[2]
        psr = psr_cal[2]
    elif isB0950:
        name = psr_names[3]
        psr = psr_cal[3]
    else:
        print(
            "\tError: No known test pulsar visible. This should not be possible"
        )
        exit()

    sun_position = get_sun(Time(obstime_utc, scale='utc'))
    moon_position = get_moon(Time(obstime_utc, scale='utc'))
    check_sun = sun_position.separation(psr)
    check_moon = moon_position.separation(psr)
    if check_sun.value < args.sun_distance:  # Can hard code this to a different value than target.
        print("\tWARNING: {} is THIS close to Sun: {:5.2f}".format(
            name, check_sun))
    if check_moon.value < 0.5:
        print("\tWARNING: {} is within 0.5 deg of the Moon!".format(name))

    slew_seconds = calc_slewtime(
        [telescope_position.ra.radian, telescope_position.dec.radian],
        [psr.ra.radian, psr.dec.radian])
    new_obstime_utc = obstime_utc + datetime.timedelta(seconds=slew_seconds)
    after_psr = observe_calibrator(new_obstime_utc, obstime=5)
    write_to_csv(csvfile, name, psr, new_obstime_utc, after_psr, pulsar=True)
    print("Scan {} observed {}.".format(i, name))
    return i, after_psr, psr, total_wait
Exemplo n.º 6
0
def do_target_observation(i, obstime_utc, telescope_position, csvfile,
                          total_wait):  #, closest_field):
    # Get objects that are close to current observing horizon:
    current_lst = Time(obstime_utc).sidereal_time('apparent', westerbork().lon)

    proposed_ra = (current_lst + Longitude('6h')).wrap_at(360 * u.deg)
    test_slew_seconds = calc_slewtime(
        [telescope_position.ra.radian, telescope_position.dec.radian],
        [proposed_ra.radian, telescope_position.dec.radian])

    avail_fields = apertif_fields[apertif_fields['weights'] > 0]
    availability = SkyCoord(
        np.array(avail_fields['hmsdms']
                 )).ra.hour - proposed_ra.hour + test_slew_seconds / 3600.
    availability[availability < -12] += 24

    targ_wait = 0  # minutes
    wait_limit = 7.0  # hours

    new_obstime_utc = obstime_utc
    # First check what is *already* up.  If nothing, then wait for something to rise.
    while not np.any((availability < 0.00) & (availability > -0.48)):
        targ_wait += dowait
        new_obstime_utc = wait_for_rise(new_obstime_utc, waittime=dowait)
        current_lst = Time(new_obstime_utc).sidereal_time(
            'apparent',
            westerbork().lon)
        proposed_ra = (current_lst + Longitude('6h')).wrap_at(360 * u.deg)
        availability = SkyCoord(np.array(
            avail_fields['hmsdms'])).ra.hour - proposed_ra.hour
        availability[availability < -12] += 24
    if (targ_wait != 0) and (targ_wait <= wait_limit * 60):
        total_wait += targ_wait
        print("\tTarget not up, waiting {} minutes until LST: {}".format(
            targ_wait, str(current_lst)))

    if targ_wait <= wait_limit * 60:
        # Choose M101 field first if available or within a 1 hour wait AND (before this function) if users had requested it in args.repeat_m101
        if 'M1403+5324' in avail_fields[(availability < 0.00)
                                        & (availability > -0.48)]['name']:
            first_field = avail_fields[avail_fields['name'] == 'M1403+5324'][0]
            print(
                "*** M1403+5324 OBSERVED!  WAIT A MONTH TO SCHEDULE AGAIN! ***"
            )
        elif 'M1403+5324' in avail_fields[(availability < 1.00)
                                          & (availability > 0)]['name']:
            m101_field = avail_fields[avail_fields['name'] == 'M1403+5324'][0]
            m101_availability = SkyCoord(
                m101_field['hmsdms']).ra.hour - proposed_ra.hour
            while not (m101_availability < 0.00) & (m101_availability > -0.48):
                targ_wait += dowait
                new_obstime_utc = wait_for_rise(new_obstime_utc,
                                                waittime=dowait)
                current_lst = Time(new_obstime_utc).sidereal_time(
                    'apparent',
                    westerbork().lon)
                proposed_ra = (current_lst + Longitude('6h')).wrap_at(360 *
                                                                      u.deg)
                m101_availability = SkyCoord(
                    m101_field['hmsdms']).ra.hour - proposed_ra.hour
                # m101_availability[m101_availability < -12] += 24
            first_field = m101_field
            print(
                "*** M1403+5324 OBSERVED!  WAIT A MONTH TO SCHEDULE AGAIN! ***"
            )
        else:
            first_field = avail_fields[(availability < 0.00)
                                       & (availability > -0.48)][0]
        sun_position = get_sun(Time(new_obstime_utc, scale='utc'))
        moon_position = get_moon(Time(new_obstime_utc, scale='utc'))
        # print("Sun position: {}".format(sun_position))
        check_sun = sun_position.separation(SkyCoord(first_field['hmsdms']))
        check_moon = moon_position.separation(SkyCoord(first_field['hmsdms']))
        if check_sun.value < args.sun_distance:
            first_field = avail_fields[(availability < 0.0)
                                       & (availability > -0.48)][-1]
            check_sun = sun_position.separation(SkyCoord(
                first_field['hmsdms']))
            print("\tShifted pointings. New field is THIS close to Sun: {}".
                  format(check_sun))

        # NOTE SLEW TIME IS CALCULATED TO THE *OBSERVING* HORIZON, NOT TO THE NEW RA!
        # TELESCOPE SHOULD MOVE TO HORIZON AND WAIT!!!
        slew_seconds = calc_slewtime(
            [telescope_position.ra.radian, telescope_position.dec.radian], [
                SkyCoord(first_field['hmsdms']).ra.radian,
                SkyCoord(first_field['hmsdms']).dec.radian
            ])
        if slew_seconds < targ_wait * 60.:
            new_obstime_utc = obstime_utc + datetime.timedelta(
                minutes=targ_wait)
        else:
            new_obstime_utc = obstime_utc + datetime.timedelta(
                seconds=slew_seconds)
        after_target = observe_target(apertif_fields,
                                      new_obstime_utc,
                                      first_field['name'],
                                      obstime=11.5)
        write_to_csv(csvfile, first_field['name'],
                     SkyCoord(first_field['hmsdms']), new_obstime_utc,
                     after_target)
        print("Scan {} observed {}.".format(i, first_field['hmsdms']))
        return i, after_target, SkyCoord(first_field['hmsdms']), total_wait
    else:
        print("\tNo target for {} hours. Go to a calibrator instead.".format(
            targ_wait / 60.))
        print(
            "\tNo target for {} hours. NEED TO EXPAND TARGET OPTIONS AND RERUN!"
            .format(targ_wait / 60.))
        return i, obstime_utc + datetime.timedelta(
            days=100), telescope_position, total_wait