예제 #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
예제 #2
0
def main():

    args = parse_args()

    print(args.beams)
    beam_range = args.beams.split(',')
    beams = range(int(beam_range[0]), int(beam_range[1]) + 1)
    freqchunks = args.bin_num
    date = args.date

    print(beams)

    basedir = args.basedir

    with open(args.task_ids) as f:
        task_id = f.read().splitlines()

    np.warnings.filterwarnings('ignore')

    # Find calibrator position
    calib = SkyCoord.from_name(args.calibname)

    cell_size = 100. / 3600.

    # Put all the output from drift_scan_auto_corr.ipynb in a unique folder per source, per set of drift scans.
    datafiles, posfiles = [], []

    for i in range(len(task_id)):
        datafiles.append('{}{}/{}_exported_data_frequency_split.csv'.format(
            basedir, task_id[i], task_id[i]))
        posfiles.append('{}{}/{}_hadec.csv'.format(basedir, task_id[i],
                                                   task_id[i]))

    datafiles.sort()
    posfiles.sort()

    # Put calibrator into apparent coordinates (because that is what the telescope observes it in.)
    test = calib.transform_to('fk5')
    calibnow = test.transform_to(
        FK5(equinox='J{}'.format(task_id2equinox(task_id[0]))))

    # Read data from tables
    data_tab, hadec_tab = [], []
    print("\nReading in all the data...")
    for file, pos in zip(datafiles, posfiles):
        data_tab.append(Table.read(file, format='csv'))  # list of tables
        hadec_tab.append(Table.read(pos, format='csv'))  # list of tables

    print("Making beam maps: ")
    for beam in beams:
        print(beam)

        for f in range(freqchunks):
            x, y, z_xx, z_yy = [], [], [], []

            for data, hadec in zip(data_tab, hadec_tab):
                hadec_start = SkyCoord(ra=hadec['ha'],
                                       dec=hadec['dec'],
                                       unit=(u.rad, u.rad))
                time_mjd = Time(data['time'] / (3600 * 24), format='mjd')
                time_mjd.delta_ut1_utc = 0  # extra line to compensate for missing icrs tables
                lst = time_mjd.sidereal_time('apparent', westerbork().lon)

                HAcal = lst - calibnow.ra  # in sky coords
                dHAsky = HAcal - hadec_start[beam].ra + (
                    24 * u.hourangle)  # in sky coords in hours
                dHAsky.wrap_at('180d', inplace=True)
                dHAphys = dHAsky * np.cos(hadec_start[beam].dec.deg *
                                          u.deg)  # physical offset in hours

                x = np.append(x, dHAphys.deg)
                y = np.append(
                    y, np.full(len(dHAphys.deg), hadec_start[beam].dec.deg))
                z_xx = np.append(
                    z_xx,
                    data['auto_corr_beam_{}_freq_{}_xx'.format(beam, f)] -
                    np.median(data['auto_corr_beam_{}_freq_{}_xx'.format(
                        beam, f)]))
                z_yy = np.append(
                    z_yy,
                    data['auto_corr_beam_{}_freq_{}_yy'.format(beam, f)] -
                    np.median(data['auto_corr_beam_{}_freq_{}_yy'.format(
                        beam, f)]))

            # Create the 2D plane, do a cubic interpolation, and append it to the cube.
            tx = np.arange(min(x), max(x), cell_size)
            ty = np.arange(min(y), max(y), cell_size)
            XI, YI = np.meshgrid(tx, ty)
            gridcubx = interpolate.griddata(
                (x, y), z_xx, (XI, YI),
                method='cubic')  # median already subtracted
            gridcuby = interpolate.griddata((x, y),
                                            z_yy, (XI, YI),
                                            method='cubic')

            # Find the reference pixel at the apparent coordinates of the calibrator
            ref_pixy = (calibnow.dec.deg -
                        min(y)) / cell_size + 1  # FITS indexed from 1
            ref_pixx = (-min(x)) / cell_size + 1  # FITS indexed from 1
            ref_pixz = 1  # FITS indexed from 1

            # Find the peak of the primary beam to normalize
            norm_xx = np.max(gridcubx[int(ref_pixy) - 3:int(ref_pixy) + 4,
                                      int(ref_pixx) - 3:int(ref_pixx) + 4])
            norm_yy = np.max(gridcuby[int(ref_pixy) - 3:int(ref_pixy) + 4,
                                      int(ref_pixx) - 3:int(ref_pixx) + 4])

            # Create 3D array with proper size for given scan set to save data as a cube
            if f == 0:
                cube_xx = np.zeros(
                    (freqchunks, gridcubx.shape[0], gridcubx.shape[1]))
                cube_yy = np.zeros(
                    (freqchunks, gridcuby.shape[0], gridcuby.shape[1]))
                db_xx = np.zeros(
                    (freqchunks, gridcubx.shape[0], gridcubx.shape[1]))
                db_yy = np.zeros(
                    (freqchunks, gridcuby.shape[0], gridcuby.shape[1]))

            cube_xx[f, :, :] = gridcubx / norm_xx
            cube_yy[f, :, :] = gridcuby / norm_yy

            # Convert to decibels
            db_xx[f, :, :] = np.log10(gridcubx / norm_xx) * 10.
            db_yy[f, :, :] = np.log10(gridcuby / norm_yy) * 10.

        stokesI = np.sqrt(0.5 * cube_yy**2 + 0.5 * cube_xx**2)
        squint = cube_xx - cube_yy

        wcs = WCS(naxis=3)
        #wcs.wcs.cdelt = np.array([-cell_size, cell_size, 12.207e3*1500])  ## I think this should be 1050, 12.207e3 is the width of 1 channel
        wcs.wcs.cdelt = np.array([-cell_size, cell_size, 12.207e3 * 1050])
        wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN', 'FREQ']
        #wcs.wcs.crval = [calib.ra.to_value(u.deg), calib.dec.to_value(u.deg), 1219.609e6+(12.207e3*(500+1500/2))] # 1280e6+(12.207e3*(-(24576/2-14000)))]
        wcs.wcs.crval = [
            calib.ra.to_value(u.deg),
            calib.dec.to_value(u.deg),
            1280e6 + (12.207e3 * (-(24576 / 2 - 14000)))
        ]
        wcs.wcs.crpix = [ref_pixx, ref_pixy, ref_pixz]
        wcs.wcs.specsys = 'TOPOCENT'
        wcs.wcs.restfrq = 1.420405752e+9
        header = wcs.to_header()

        hdux = fits.PrimaryHDU(cube_xx, header=header)
        hduy = fits.PrimaryHDU(cube_yy, header=header)
        hduI = fits.PrimaryHDU(stokesI, header=header)
        hdusq = fits.PrimaryHDU(squint, header=header)

        if not os.path.exists(basedir + 'fits_files/{}/'.format(date)):
            os.mkdir(basedir + 'fits_files/{}/'.format(date))

        # Save the FITS files
        hdux.writeto(basedir + 'fits_files/{}/{}_{}_{:02}_xx.fits'.format(
            date, args.calibname.replace(" ", ""), date, beam),
                     overwrite=True)
        hduy.writeto(basedir + 'fits_files/{}/{}_{}_{:02}_yy.fits'.format(
            date, args.calibname.replace(" ", ""), date, beam),
                     overwrite=True)
        hduI.writeto(basedir + 'fits_files/{}/{}_{}_{:02}_I.fits'.format(
            date, args.calibname.replace(" ", ""), date, beam),
                     overwrite=True)
        hdusq.writeto(basedir + 'fits_files/{}/{}_{}_{:02}_diff.fits'.format(
            date, args.calibname.replace(" ", ""), date, beam),
                      overwrite=True)
예제 #3
0
        'template'
    ]
else:
    header = [
        'source', 'ra', 'ha', 'dec', 'date1', 'time1', 'date2', 'time2', 'int',
        'type', 'weight', 'beam', 'switch_type', 'freqmode', 'centfreq',
        'template'
    ]

print("Will shift pointings if Sun is within {} degrees.".format(
    args.sun_distance))

# Estimate the telescope starting position as on the meridian (approximately parked)
telescope_position = SkyCoord(ra=Time(args.starttime_utc).sidereal_time(
    'apparent',
    westerbork().lon),
                              dec='50d00m00s')
current_lst = Time(args.starttime_utc).sidereal_time('apparent',
                                                     westerbork().lon)
next_cal = 'flux'
if args.pol_cal_true:
    next_cal = 'pol'
if (current_lst.hour - pol_cal[1].ra.hour >
        -5.0) and (current_lst.hour - pol_cal[1].ra.hour < 0.1):
    next_cal = 'pol'

# Create a record of the positions planned to be observed so we can plot later.
observed_pointings = []

# Keep track of idle time.
total_wait = 0
예제 #4
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
예제 #5
0
        'template'
    ]
else:
    header = [
        'source', 'ra', 'ha', 'dec', 'date1', 'time1', 'date2', 'time2', 'int',
        'type', 'weight', 'beam', 'switch_type', 'freqmode', 'centfreq',
        'template'
    ]

print("Will shift pointings if Sun is within {} degrees.".format(
    args.sun_distance))

# Estimate the telescope starting position as on the meridian (approximately parked)
telescope_position = SkyCoord(ra=Time(args.starttime_utc).sidereal_time(
    'apparent',
    westerbork().lon),
                              dec='50d00m00s')
current_lst = Time(args.starttime_utc).sidereal_time('apparent',
                                                     westerbork().lon)
next_cal = 'flux'
# Start on polarization calibrator rather than flux cal if user specified:
if args.pol_cal_true:
    next_cal = 'pol'
if (current_lst.hour - pol_cal[1].ra.hour >
        -5.0) and (current_lst.hour - pol_cal[1].ra.hour < 0.1):
    next_cal = 'pol'

# Create a record of the positions planned to be observed so we can plot later.
observed_pointings = []

# Keep track of idle time.
예제 #6
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
예제 #7
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
예제 #8
0
elif os.path.isfile(csv_filename) & os.path.isfile(args.previous_obs):
    print("Specified output file exists; appending schedule to previous file {}".format(csv_filename))
    header = False
elif os.path.isfile(csv_filename):
    print("Output file {} exists but not specified with '-p', so overwriting.".format(csv_filename))
    os.remove(csv_filename)
    header = ['source', 'ra', 'ha', 'dec', 'date1', 'time1', 'date2', 'time2', 'int', 'type', 'weight', 'beam',
              'switch_type', 'freqmode', 'centfreq', 'template']
else:
    header = ['source', 'ra', 'ha', 'dec', 'date1', 'time1', 'date2', 'time2', 'int', 'type', 'weight', 'beam',
              'switch_type', 'freqmode', 'centfreq', 'template']

print("Will shift pointings if Sun is within {} degrees.".format(args.sun_distance))

# Estimate the telescope starting position as on the meridian (approximately parked)
telescope_position = SkyCoord(ra=Time(args.starttime_utc).sidereal_time('apparent', westerbork().lon), dec='50d00m00s')
current_lst = Time(args.starttime_utc).sidereal_time('apparent', westerbork().lon)
next_cal = 'flux'
if args.pol_cal_true:
    next_cal = 'pol'
# if (current_lst.hour - pol_cal[1].ra.hour > -5.0) and (current_lst.hour - pol_cal[1].ra.hour < 0.1):
#     next_cal = 'pol'

# Create a record of the positions planned to be observed so we can plot later.
observed_pointings = []

# Keep track of idle time.
total_wait = 0

# Do the observations: select calibrators and target fields, and write the output to a CSV file.
# Also, writes out a record of what is observed, when, and if the telescope has to wait for objects to rise.
예제 #9
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
예제 #10
0
        if (dict(observations[i])['name'][0:2] != '3c') and (
            dict(observations[i])['name'][0:2] != '3C') and (
                dict(observations[i])['name'][0:2] != 'CT')
    ]
    # Adjust 'weights' field for objects that have been previously observed:
    for obs in timing_obs:
        if obs in fields['name']:
            i = np.where(timing_fields['name'] == obs)
            timing_fields['weights'][i] -= 1
else:
    print("Not querying ATDB for previous observations.")

# Estimate the telescope starting position as on the meridian (approximately parked)
telescope_position = SkyCoord(ra=Time(args.starttime_utc).sidereal_time(
    'apparent',
    westerbork().lon),
                              dec='50d00m00s')

# Create a record of the positions planned to be observed so we can plot later.
observed_pointings = []

print("\nStarting observations! UTC: " + str(args.starttime_utc))
print("Calculating schedule for the following " + str(args.schedule_length) +
      " days.\n")

# Keep track of observing efficiency
total_wait = 0
# Could expand code to include the option of picking the field to start with.
closest_field = None

# Open & prepare CSV file to write parset parameters to, in format given by V.M. Moss.
예제 #11
0
def main():

    args = parse_args()

    # User supplied **UTC** start time:
    start_obstime_utc = args.starttime_utc
    current_lst = Time(start_obstime_utc).sidereal_time('apparent', westerbork().lon)

    # User supplied calibrator:
    calib_name = args.calib
    drift_cal = SkyCoord.from_name(calib_name)

    # Convert to apparent coordinates for setting up the observations
    test = drift_cal.transform_to('fk5')
    drift_cal = test.transform_to(FK5(equinox='J'+str(Time(start_obstime_utc).decimalyear)))

    print("\n##################################################################")
    print("Calibrator is: {}".format(calib_name))
    print("Calibrator position is: {} in J{:7.2f} coordinates".format(drift_cal.to_string('hmsdms'), Time(start_obstime_utc).decimalyear))
    print("\t in degrees: {} {}".format(drift_cal.ra.deg, drift_cal.dec.deg))

    print("Starting LST is :", current_lst)

    wrap = 0 * u.hourangle
    if (current_lst-drift_cal.ra).value > 12.0:
        wrap = 24 * u.hourangle
    if (current_lst-drift_cal.ra).value < -12.0:
        wrap = -24 * u.hourangle

    print("Starting HA of calibrator is: {}".format(current_lst-drift_cal.ra-wrap))
    if np.abs((current_lst-drift_cal.ra-wrap).hourangle) > 6.:
        print("CALIBRATOR IS NOT ACTUALLY UP (but calculations are still right).")
    print("")

    beams = read_beams()

    rows = np.array(unique(beams, keys='dDec'))

    diff = rows[0][1] - rows[1][1]

    print("Starting observations! UTC: {}".format(args.starttime_utc))

    # Calculate the starting position of the beams and the length of the drift
    # (Do for multiple options which will print if ags.verbose = True):
    for n in range(1,5):
        # Only include explicit drift through beam 0 if only drifting through peak.
        if n > 1:
            r_nozero = np.delete(rows, 3)
        else:
            r_nozero = rows
        dec_cen = []
        dec_row = []
        ra_start = []
        ha_start = []
        ha_end = []
        drift_time = []
        # Add drifts at the start
        if n > 1:
            # for i in range(n + 0, 0, -1):  # changed from n-1
            #     dec_row.append(drift_cal.dec.deg + rows[0][1] + (diff) / (n-1) * i)
            #     dec_cen.append(drift_cal.dec.deg - rows[0][1] - (diff) / (n-1) * i)
            for i in range(n + 2, 0, -1):  # Regular density of scans outside first row
                dec_row.append(drift_cal.dec.deg + rows[0][1] + (diff) / (n) * i)
                dec_cen.append(drift_cal.dec.deg - rows[0][1] - (diff) / (n) * i)
            # Drift starts at high RA, low HA
                ha_start.append(np.min(beams[np.where(beams['dDec'] == rows[0][1])]['dHA']))
                ha_end.append(np.max(beams[np.where(beams['dDec'] == rows[0][1])]['dHA']))
                ra_start.append(drift_cal.ra.deg + (ha_start[-1] - 0.9) / np.cos(dec_row[-1] * u.deg))
                drift_time.append((np.abs(ha_end[-1] - ha_start[-1] + 1.8) / np.cos((dec_row[-1]) * u.deg)) * 12. / 180. * 60. * u.min)
        # Do drifts for all the beams
        for r in r_nozero[:-1]:
            for i in range(n):
                dec_row.append(drift_cal.dec.deg + r[1] - (diff) / n * i)
                dec_cen.append(drift_cal.dec.deg - r[1] + (diff) / n * i)
                ha_start.append(np.min(beams[np.where(beams['dDec'] == r[1])]['dHA']))
                ha_end.append(np.max(beams[np.where(beams['dDec'] == r[1])]['dHA']))
                ra_start.append(drift_cal.ra.deg + (ha_start[-1] - 0.9) / np.cos(dec_row[-1] * u.deg))
                drift_time.append((np.abs(ha_end[-1] - ha_start[-1] + 1.8) / np.cos((dec_row[-1]) * u.deg)) * 12. / 180. * 60. * u.min)
        # Add drifts at the end
        if n > 1:
            for i in range(0, n+3):  # changed from n-1
                dec_row.append(drift_cal.dec.deg + rows[-1][1] - (diff) / (n) * i)
                dec_cen.append(drift_cal.dec.deg - rows[-1][1] + (diff) / (n) * i)
                # Drift starts at high RA, low HA
                ha_start.append(np.min(beams[np.where(beams['dDec'] == rows[-1][1])]['dHA']))
                ha_end.append(np.max(beams[np.where(beams['dDec'] == rows[-1][1])]['dHA']))
                ra_start.append(drift_cal.ra.deg + (ha_start[-1] - 0.75) / np.cos(dec_row[-1] * u.deg))
                drift_time.append((np.abs(ha_end[-1] - ha_start[-1] + 1.5) / np.cos((dec_row[-1]) * u.deg)) * 12. / 180. * 60. * u.min)

        start_pos = SkyCoord(ra=np.array(ra_start), dec=dec_cen, unit='deg')

        if args.verbose and (int(args.drifts_per_beam) != n):
            print("Drift time: {}".format([drift_time[i].value for i in range(len(drift_time))]))
            print("Number of drifts/beam (approx): {}.".format(n))
            print("Total time: {}.\n".format(np.ceil(sum(drift_time) + 2. * (len(drift_time)-1) * u.min)))

        if (args.verbose and int(args.drifts_per_beam) == n) or (int(args.drifts_per_beam) == n):
            print("Drift time: {}".format([drift_time[i].value for i in range(len(drift_time))]))
            print("Number of drifts/beam (approx): {}.".format(n))
            print("Total time: {}.\n".format(np.ceil(sum(drift_time) + 2. * (len(drift_time)-1) * u.min)))

            # Plot and save the drifts for the one actually requested:
            fig,ax=plt.subplots(figsize=(9, 6))
            ax.scatter(drift_cal.ra.deg, drift_cal.dec.deg, c='red', s=20)
            ax.scatter(drift_cal.ra.deg + beams['dHA'] / np.cos((drift_cal.dec.deg + beams['dDec']) * u.deg),
                   drift_cal.dec.deg + beams['dDec'], s=10, marker='o', facecolor='black')
            ax.scatter(drift_cal.ra.deg + beams['dHA'] / np.cos((drift_cal.dec.deg + beams['dDec']) * u.deg),
                   drift_cal.dec.deg + beams['dDec'], s=3000, marker='o', color="none", edgecolors='k')
            ax.scatter(ra_start, dec_row, s=10, marker='*', facecolor='brown')
            
            for i in range(len(dec_cen)):
                # ax.plot([ra_start[i], ra_start[i] + (ha_end[i] - ha_start[i] + 1.2) / np.cos((dec_row[i]) * u.deg)],
                ax.plot([ra_start[i], ra_start[i] + drift_time[i] / u.min / 60. /12. * 180.],
                        [dec_row[i], dec_row[i]])

            xlims = ax.get_xlim()
            plt.xlim(xlims[1]+0.25,xlims[0]-0.25)
            ax.set_xlabel("RA [deg]", fontsize=20)
            ax.set_ylabel("DEC [deg]", fontsize=20)
            figfilename = calib_name.replace(' ', '') + '_driftscan.png'
            plt.savefig(figfilename, dpi=200, bbox_inches='tight')

            # Open & prepare CSV file to write parset parameters to, in format given by V.M. Moss.
            # Don't worry about slew time because 2 minute wait will always be longer.
            with open(calib_name.replace(' ','') + "_drift" + args.starttime_utc.strftime("%Y%m%d") + args.output + ".csv", "w") as csvfile:
                csvfile.write('source,ra,ha,dec,date1,time1,date2,time2,int,type,weight,beam,switch_type,freqmode,centfreq,template\n')
                for i in range(len(dec_cen)):
                    sidereal_t = Time(start_obstime_utc).sidereal_time('apparent', westerbork().lon)
                    wrap = 0 * u.hourangle
                    if (sidereal_t - drift_cal.ra).value > 12.0 :
                        wrap = 24 * u.hourangle
                    if (sidereal_t - drift_cal.ra).value < -12.0 :
                        wrap = -24 * u.hourangle
                    telescope_position_hadec = sidereal_t - start_pos[i].ra - wrap
                    end_obstime_utc = do_drift(start_obstime_utc, drift_time[i].value)
                    date1, time1 = start_obstime_utc.strftime('%Y-%m-%d'), start_obstime_utc.strftime('%H:%M:%S')
                    date2, time2 = end_obstime_utc.strftime('%Y-%m-%d'), end_obstime_utc.strftime('%H:%M:%S')
                    offset = (drift_cal.dec.deg - dec_cen[i]) * 60.     # units in arcmins
                    sign = '+' if int(offset) >= 0 else '-'
                    csvfile.write('{}drift{}{:02},,{:.6f},{:.6f},{},{},{},{},10,T,compound,0,system,300,1280,{}\n'.format(calib_name.replace(' ',''),
                                                        sign, int(np.abs(offset)),telescope_position_hadec.deg, dec_cen[i], date1, time1, date2, time2,
                                                        '/opt/apertif/share/parsets/parset_start_observation_atdb_SubbandPhaseCorrection.template'))
                    start_obstime_utc = end_obstime_utc + datetime.timedelta(minutes=2.0)
                    
            print(end_obstime_utc)
            

                


    # Don't add the last 2 minutes to write out the end time because we don't care about the delay for the data writer.
    print("Assuming {} drifts, ending observations! UTC: {}".format(args.drifts_per_beam,end_obstime_utc))

    print("CSV file written to {}".format(csvfile.name))
    print("PNG file written to {}".format(figfilename))
    print("##################################################################\n")
예제 #12
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
예제 #13
0
def main():

    args = parse_args()

    np.warnings.filterwarnings('ignore')

    # Find calibrator position
    calib = SkyCoord.from_name(args.calibname)

    # Put all the output from drift_scan_auto_corr.ipynb in a unique folder per source, per set of drift scans.
    datafiles = glob(args.root + '*exported_data.csv')
    datafiles.sort()
    posfiles = glob(args.root + '*hadec.csv')
    posfiles.sort()

    # Put calibrator into apparent coordinates (because that is what the telescope observes it in.)
    test = calib.transform_to('fk5')
    calibnow = test.transform_to(FK5(equinox='J{}'.format(taskid2equinox(args.taskid))))

    corr_im = []
    diff_im = []
    for beam in range(40):
        print(beam, end=' ')
        # Create the vectors which contain all data from all scans for a given beam which has been specified above.
        x, y, z_xx, z_yy = [], [], [], []
        for file, pos in zip(datafiles, posfiles):
            data = Table.read(file, format='csv')
            hadec = Table.read(pos, format='csv')
            hadec_start = SkyCoord(ra=hadec['ha'], dec=hadec['dec'], unit=(u.rad, u.rad))  # From ALTA (same as above)

            time_mjd = Time(data['time'] / (3600 * 24), format='mjd')
            lst = time_mjd.sidereal_time('apparent', westerbork().lon)

            HAcal = lst - calibnow.ra  # in sky coords
            dHAsky = HAcal - hadec_start[beam].ra + (24 * u.hourangle)  # in sky coords in hours
            dHAsky.wrap_at('180d', inplace=True)
            dHAphys = dHAsky * np.cos(hadec_start[beam].dec.deg * u.deg)  # physical offset in hours

            x = np.append(x, dHAphys.deg)
            y = np.append(y, np.full(len(dHAphys.deg), hadec_start[beam].dec.deg))
            z_xx = np.append(z_xx, data['auto_corr_beam_' + str(beam) + '_xx'] - np.median(
                data['auto_corr_beam_' + str(beam) + '_xx']))
            z_yy = np.append(z_yy, data['auto_corr_beam_' + str(beam) + '_yy'] - np.median(
                data['auto_corr_beam_' + str(beam) + '_yy']))

        # # Add a fake drift that goes to zero power at 1 deg above last scan
        # x=np.append(x,dHAphys.deg)
        # y=np.append(y,np.full(len(dHAphys.deg),max(y)+1.0))
        # z_xx=np.append(z_xx,np.full(len(dHAphys.deg),1))
        # z_yy=np.append(z_yy,np.full(len(dHAphys.deg),1))

        # # Add a fake drift that goes to zero power at 1 deg below first scan
        # x=np.append(x,dHAphys.deg)
        # y=np.append(y,np.full(len(dHAphys.deg),min(y)-1.0))
        # z_xx=np.append(z_xx,np.full(len(dHAphys.deg),1))
        # z_yy=np.append(z_yy,np.full(len(dHAphys.deg),1))

        # Create the 2D grid and do a cubic interpolation
        cell_size = 105. / 3600.
        tx = np.arange(min(x), max(x), cell_size)
        ty = np.arange(min(y), max(y), cell_size)
        XI, YI = np.meshgrid(tx, ty)
        gridcubx = interpolate.griddata((x, y), z_xx, (XI, YI), method='cubic')  # median already subtracted
        gridcuby = interpolate.griddata((x, y), z_yy, (XI, YI), method='cubic')

        # Find the reference pixel at the apparent coordinates of the calibrator
        ref_pixy = (calibnow.dec.deg - min(y)) / cell_size
        ref_pixx = (-min(x)) / cell_size

        # Find the peak of the primary beam to normalize
        norm_xx = np.max(gridcubx[int(ref_pixy)-3:int(ref_pixy)+4, int(ref_pixx)-3:int(ref_pixx)+4])
        norm_yy = np.max(gridcuby[int(ref_pixy) - 3:int(ref_pixy) + 4, int(ref_pixx) - 3:int(ref_pixx) + 4])
        if beam == 0:
            norm0_xx = np.max(gridcubx[int(ref_pixy) - 3:int(ref_pixy) + 4, int(ref_pixx) - 3:int(ref_pixx) + 4])
            norm0_yy = np.max(gridcuby[int(ref_pixy) - 3:int(ref_pixy) + 4, int(ref_pixx) - 3:int(ref_pixx) + 4])

        # Convert to decibels
        db_xx = np.log10(gridcubx/norm_xx) * 10.
        db_yy = np.log10(gridcuby/norm_yy) * 10.
        # db0_xx = np.log10(gridcubx/norm0_xx) * 10.
        # db0_yy = np.log10(gridcuby/norm0_yy) * 10.

        wcs = WCS(naxis=2)
        wcs.wcs.cdelt = np.array([-cell_size, cell_size])
        wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN']
        wcs.wcs.crval = [calib.ra.to_value(u.deg), calib.dec.to_value(u.deg)]
        wcs.wcs.crpix = [ref_pixx, ref_pixy]
        header = wcs.to_header()

        hdux_db = fits.PrimaryHDU(db_xx, header=header)
        hduy_db = fits.PrimaryHDU(db_yy, header=header)
        hdux = fits.PrimaryHDU(gridcubx/norm_xx, header=header)
        hduy = fits.PrimaryHDU(gridcuby/norm_yy, header=header)
        # hdulx = fits.HDUList([hdux])
        # hduly = fits.HDUList([hduy])

        # Save the FITS files
        hdux_db.writeto(args.root + '{}_{}_{:02}xx_db.fits'.format(args.calibname.replace(" ", ""), args.taskid[:-3],
                                                                   beam), overwrite=True)
        hduy_db.writeto(args.root + '{}_{}_{:02}yy_db.fits'.format(args.calibname.replace(" ", ""), args.taskid[:-3],
                                                                   beam), overwrite=True)
        hdux.writeto(args.root + '{}_{}_{:02}xx.fits'.format(args.calibname.replace(" ", ""), args.taskid[:-3],
                                                             beam), overwrite=True)
        hduy.writeto(args.root + '{}_{}_{:02}yy.fits'.format(args.calibname.replace(" ", ""), args.taskid[:-3],
                                                             beam), overwrite=True)

        fig1 = plt.figure(figsize=(6, 9))
        ax1 = fig1.add_subplot(2, 1, 1, projection=wcs.celestial)
        ax1.grid(lw=1, color='white')
        ax1.set_title("Beam {:02} - XX Correlation - Cubic".format(beam))
        ax1.set_ylabel("Declination [J2000]")
        ax1.set_xlabel("Right Ascension [J2000]")
        im1 = ax1.imshow(gridcubx/norm0_xx, vmax=0.10, vmin=-0.03, cmap='magma', animated=True)
        ax2 = fig1.add_subplot(2, 1, 2, projection=wcs.celestial)
        ax2.grid(lw=1, color='white')
        ax2.set_title("Beam {:02} - YY Correlation - Cubic".format(beam))
        ax2.set_ylabel("Declination [J2000]")
        ax2.set_xlabel("Right Ascension [J2000]")
        im2 = ax2.imshow(gridcuby/norm0_yy, vmax=0.10, vmin=-0.03, cmap='magma', animated=True)
        corr_im.append([im1, im2])
        plt.savefig(args.root + '{}_{}_{:02}db0_reconstructed.png'.format(args.calibname.replace(" ", ""),
                                                                          args.taskid, beam))
        plt.close('all')

        # Plot the difference between XX and YY for every beam
        diffcub = gridcubx/norm_xx - gridcuby/norm_yy

        fig2 = plt.figure(figsize=(10, 9))
        ax1 = fig2.add_subplot(1, 1, 1, projection=wcs.celestial)
        ax1.grid(lw=1, color='white')
        ax1.set_title("Beam {:02} - Difference (XX$-$YY)".format(beam))
        ax1.set_ylabel("Declination [J2000]")
        ax1.set_xlabel("Right Ascension [J2000]")
        ax1.scatter(ref_pixx, ref_pixy, marker='x', color='black')
        im3 = ax1.imshow(diffcub, vmin=-0.1, vmax=0.1)
        plt.colorbar(im3)
        diff_im.append([im3])
        plt.savefig(args.root + '{}_{}_{:02}_difference.png'.format(args.calibname.replace(" ", ""),
                                                                    args.taskid, beam))
        plt.close('all')

    if args.make_gifs:
        make_gifs(args.root)