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
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
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
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
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
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