From CARMA
# -*- python -*-
import obsdef2 as od
"""
Contact Person for project cs016
Name : John Carpenter
Email : jmc@astro.caltech.edu
Office phone : 626-398-2036
Home phone : 626-395-4024
--------------------------------------------------------------------------------
Instructions for the observers:
--------------------------------------------------------------------------------
Source : Orion
RA : 05:35:14.16
Dec : -05:22:21.50
---------------------------------------------------------------------
Rise/Set LST times for source/phase-calibrator at elevation of 20.0 degrees
Source Rise Set
Orion 01:36:01 09:34:27 --- Up for 8.0 hours
0609-157 02:54:54 09:24:28 --- Phase calibrator
"""
# ----------------------- OPTIONS SPECIFIED BY THE PI ------------------------
projectInfo = {
'emailAddress' : 'jmc@astro.caltech.edu',
'code' : 'cs016',
'obsblock' : 'orion',
'subobsblock' : None,
'sourceCatalog' : 'cs016.cat',
}
# Tuning options
tuning = {
'restfreq' : linefreq('12CO(1-0)'), # Alternate way to specify rest frequency
'sideband' : USB, # Sideband for first LO (LSB or USB)
'IFfreq' : 1.79, # [GHz] IF frequency
}
# Correlator configuration for science target
configband(1, BW500, tuning['restfreq'])
configband(2, BW8, tuning['restfreq'])
configband(3, BW500, tuning['restfreq']+0.46)
# Correlator configuration for calibrators
# reconfig: Sets correlator configuration for calibration observations
# None : same as for science targets
# od.CORR_BW500LO6: 500 MHz, non-overlapping bands in BIMA IF
# od.CORR_BW500LO : 500 MHz, non-overlapping bands (not recommended for 3mm)
# od.CORR_BW500 : change bands to 500 MHz without changing IF
# hybrid: Correlator configurations to calibrate band offsets (see FAQ page!).
# Needed only if all bands have width < 500 MHz.
# tintHybrid : integration time for each of the hybrid correlator modes
#
# Do not use hybrid mode unless you really have to!!!
#
correlator = {
'reconfig' : None,
'hybrid' : None,
#'hybrid' : [ [BW500, BW62, BW62], [BW62, BW500, BW62] ],
'tintHybrid' : 5.0,
}
# Names for phase calibrators and science targets.
# Enter multiple science targets as 'target' : 'ABAur, GMAur',
# Enter multiple phase calibrators as
# 'phaseCal' : [ '3c111 1:00:00 4:00:00',
# '0530+135 3:30:00 7:00:00'],
# tintTarget: Integration time per cycle **per pointing** on science targets
# tintPhase : Phase calibrator integration time per cycle
# callist : Used to search for bright phase calibrators. See online manual
sources = {
'target' : 'Orion',
'phaseCal' : '0609-157',
'tintTarget' : 15.00, # [minutes] time per cycle *** per pointing ***
'tintPhaseCal' : 3.00, # [minutes]
'callist' : None,
}
# Mosaic options
mosaic = {
'doMosaic' : False, # If True, make a mosaic
'startpos' : 1, # Starting mosaic position
'nphase' : 0, # Number of positions to observe between phase cal
# observations. 0 -> Observe all positions.
'arcminUnits': True, # If True, offsets are in arcminutes. If False,
# offsets are in units of the Nyquist sampling rate
# of the large antenna in the subarray
'offsetFile' : None, # Offset data file (e.g. 'm51_mosaic.dat')
'offsets' : None, # List containing the offsets.
# This can be used instead of offsetFile.
# e.g. [ [-0.5,0.5], [0.5,-0.5], [-0.5,-0.5]]
}
# Pointing options
pointing = {
'doPointNight' : True, # If True, then perform radio pointing during nightime
'doPointDay' : True, # If True, then perform radio pointing during daytime
'intervalNight': 4.0, # [hours] How often to point during nighttime
'intervalDay' : 2.0, # [hours] How often to point during daytime
'minflux' : 2.00, # [Jy] Minimum pointing flux
'maxsep' : 50, # [degree] Maximum distance from science target
'preferred' : None, # Preferred pointing source
'nrepInt' : 1, # Number of repeat observations per position
'mapPoints' : 5, # Make a strip in az/el with mapPoints positions
'tune95' : False, # Tune to 95 GHz before pointing
'sunriseset' : True, # If True, point immediately after sunrise/sunset
}
# Passband options
passband = {
'doPassband' : True, # If True, observe passband calibrator
'doPoint' : False, # Point up on passband calibrator if needed
'forcePoint' : False, # Force pointing if source is available
'tint' : 15.00, # [minutes] Passband calibrator integration time
'minflux' : 4.00 , # [Jy] Minimum flux density for passband cal
'preferred' : None, # Preferred passband calibrator
'middle' : False, # OK to observe in middle of phase/source cycle?
'ncal' : 1, # Maximum number of calibrators to observe per track
'interval' : None, # [hours] How frequently to perform passband cal
}
# Flux calibration options
fluxcal = {
'doPrimary' : True, # If True, observe primary flux calibrators
'doSecondary' : True, # If True, observe secondary calibrator if primary
# calibrator is not available
'doBoth' : False, # Observe both primary/secondary cal in each cycle
'doPoint' : True, # Point up on flux calibrator if needed
'forcePoint' : False, # Force pointing if source is available
'tint' : 5.00, # [minutes] Integration time per calibrator
'preferredPri' : None, # Preferred primary calibrators
'preferredSec' : None, # Preferred secondary calibrators
'ncal' : 1, # Number of calibrators to observe per cycle
'ncycles' : 1, # Maximum number of calibration cycles in track
'interval' : 2.0, # [hours] How often to repeat calibration cycles
'middle' : False, # OK to observe in middle of phase/source cycle?
}
# Indicate, True or False, which primary flux calibrators are ok to use.
# Add sources to the list as needed.
primaryFluxCalibrators = {
'jupiter' : False,
'mars' : True,
'neptune' : True,
'uranus' : True,
'mercury' : False,
'mwc349' : True,
}
# Set various limits for observations
# minElevationCal : Minimum elevation for flux/passband/pointing sources
# maxElevationCal : Maximum elevation for flux/passband/pointing sources
# trackingThreshold: Data are flagged if tracking error is larger than limit.
# record : Record length for integrations (except noise source)
# tmoTrack : Timeout when acquiring a source
# tsys : Time between full tsys measurements
# antwait : Number of antennas to arriveon source before integrating
limits = {
'minElevationCal' : 30.0, # [degrees]
'maxElevationCal' : 80.0, # [degrees]
'trackingThreshold' : 0.1, # [beamwidths]
'record' : 30.00, # [seconds]
'tmoTrack' : 500.0, # [seconds]
'tsys' : 10.0, # [minutes]
'antwait' : -2,
}
# Noise source parameters
noise = {
'tint' : 2, # [seconds] Integration time for noise source
'record' : 2, # [seconds] Record length for noise integration only
}
# ----------------------- END OF PI SPECIFIED OPTIONS --------------------------
# ----------------------- MAIN PART OF SCRIPT --------------------------
# Initialize system
od.initializeTrack(sources, mosaic, projectInfo, limits, pointing, passband,
fluxcal, restart=restartScript, scriptName=scriptName,
scriptOptions=scriptOptions)
# Check that sources are in the current catalogs
od.trackMessage('Verifying source names')
od.checkSources(sources['target'], indent=1)
od.checkSources(sources['phaseCal'], indent=1, isPhase=True)
od.checkSources(sources['callist'], indent=1)
od.checkSources(fluxcal['preferredPri'], indent=1)
od.checkSources(fluxcal['preferredSec'], indent=1)
od.checkSources(passband['preferred'], indent=1)
od.checkSources(pointing['preferred'], indent=1)
od.checkSources(primaryFluxCalibrators, indent=1)
# Tune receivers
if od.tuneReceivers():
od.trackMessage("Tuning freq=" + str("%.3f" % tuning['restfreq']) + " GHz, " +
str(tuning['sideband']) + ", IFfreq=" + str("%.3f" % tuning['IFfreq']) + " GHz")
freq(tuning['restfreq'], tuning['sideband'], tuning['IFfreq'], \
od.getSourceName(sources['target'], n=1, parse=True))
# Set the correlator configuration for calibrations observations if it is
# different from the science observations.
checkbands()
correlator['configCal'] = None
if correlator.has_key('reconfig') and correlator['reconfig'] <> None:
od.trackMessage('Determining correlator configuration for calibrator observations')
correlator['configCal'] = od.setCorrCal(correlator['reconfig'])
# Set IF levels in antenas/downconverters for calibrator correlator config.
od.setIFLevels(correlator)
# Send email indicating track has started.
# fullScriptName and scriptOptions are set in run().
if od.emailScriptLog():
od.sendEmail(projectInfo['code'], projectInfo['emailAddress'],
fullScriptName, scriptOptions,
start=True, restart=restartScript)
# Measure optical-radio pointing vector, if needed
if pointing['doOptPoint']: od.measureOptradVector(pointing, correlator)
# Flux calibration
od.doFluxcal(fluxcal, primaryFluxCalibrators, noise, correlator, pointing,
ref=sources['target'], start=True)
# Passband
od.doPassband(passband, correlator, noise, pointing, ref=sources['target'],
start=True)
# Radio pointing
od.doPoint(pointing, ref=sources['target'], correlator=correlator, start=True)
# Choose phase calibrator. Only meaningful if sources[callist] is set.
sources['phaseCal'],sources['tintPhaseCal'] = \
od.findCalibrator(sources, correlator=correlator)
# Observe passband calibrator until source and first phase calibrator are up
pname, tstart, tstop = od.getPhaseCal(sources['phaseCal'])
waitingForSource = not sources['doSnapshot']
while waitingForSource:
dt = od.timeRemaining(source=sources['target'], phase=pname,
lsttime=od.getLstStartCycle(tstart), toRise=True)
if dt > 0:
od.trackMessage('Waiting for source to rise - observing passband for '
+ od.dtString(dt))
ok = od.doPassband(passband, correlator, noise, pointing,
lststop=tstart, ref=sources['target'], force=True)
if not ok: waitingForSource = False
else:
waitingForSource = False
# Cycle between source and phase calibrator.
od.doSourcesPhasecal(sources, fluxcal, pointing, passband, correlator,
noise, mosaic=mosaic, primaryCal=primaryFluxCalibrators)
# Passband observations
od.doPassband(passband, correlator, noise, pointing, ref=sources['target'])
# Flux calibration
od.doFluxcal(fluxcal, primaryFluxCalibrators, noise, correlator, pointing,
ref=sources['target'])
# Print track summary
od.trackSummary()
# Send email indicating track is finished
if od.emailScriptLog():
od.sendEmail(projectInfo['code'], projectInfo['emailAddress'],
fullScriptName, scriptOptions, msg=od.getTrackHistory())
# Done
resetProject()
if endTrackAlarm(): alarmon();