Source code for pipeline.hifv.heuristics.vlascanheuristics

import datetime
import math

import numpy

import pipeline.infrastructure.logging as logging
from pipeline.infrastructure import casa_tools

# the logger for this module
LOG = logging.get_logger(__name__)


[docs]def buildscans(msfile, scd): """ buildscans: compile scan information for msfile Created S.T. Myers 2012-05-07 v1.0 Updated S.T. Myers 2012-05-14 v1.1 add corrtype Updated S.T. Myers 2012-06-27 v1.2 add corrdesc lookup Updated S.T. Myers 2012-11-13 v2.0 STM casa 4.0 new calls Usage: from lib_EVLApipeutils import buildscans Input: msfile - name of MS Output: scandict (return value) Examples: CASA <2>: from lib_EVLApipeutils import buildscans CASA <3>: msfile = 'TRSR0045_sb600507.55900.ms' CASA <4>: myscans = buildscans(msfile) Getting scansummary from MS Found 16 DataDescription IDs Found 4 StateIds Found 3422 times in DD=0 Found 3422 times in DD=1 Found 3422 times in DD=2 Found 3422 times in DD=3 Found 3422 times in DD=4 Found 3422 times in DD=5 Found 3422 times in DD=6 Found 3422 times in DD=7 Found 3422 times in DD=8 Found 3422 times in DD=9 Found 3422 times in DD=10 Found 3422 times in DD=11 Found 3422 times in DD=12 Found 3422 times in DD=13 Found 3422 times in DD=14 Found 3422 times in DD=15 Found total 54752 times Found 175 scans min=1 max=180 Size of scandict in memory is 248 bytes CASA <5>: myscans['Scans'][1]['intents'] Out[5]: 'CALIBRATE_AMPLI#UNSPECIFIED,UNSPECIFIED#UNSPECIFIED' CASA <6>: myscans['Scans'][1]['dd'] Out[6]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] CASA <7>: myscans['DataDescription'][0] Out[7]: {'corrdesc': ['RR', 'RL', 'LR'', 'LL'], 'corrtype': [5, 6, 7, 8], 'ipol': 0, 'nchan': 64, 'npol': 4, 'reffreq': 994000000.0, 'spw': 0, 'spwname': 'Subband:0'} CASA <8>: myscans['Scans'][1]['times'][0] Out[8]: [4829843281.500001, 4829843282.5, 4829843283.5, 4829843284.5, ... 4829843336.5] The last of these returns the integration midpoints for scan 1 DD 0. Note that to get spw and pol info you use the DD indexes from ['dd'] in the 'Scans' part to index into the 'DataDescription' info. You can also list the keys available in the Scans sub-dictionary: CASA <9>: myscans['Scans'][1].keys() Out[9]: ['scan_mid', 'intents', 'field', 'dd', 'npol', 'rra', 'spw', 'scan_int', 'scan_start', 'times', 'scan_end', 'rdec'] """ # dictionary with lookup for correlation strings # from http://casa.nrao.edu/docs/doxygen/html/classcasa_1_1Stokes.html cordesclist = ['Undefined', 'I', 'Q', 'U', 'V', 'RR', 'RL', 'LR', 'LL', 'XX', 'XY', 'YX', 'YY', 'RX', 'RY', 'LX', 'LY', 'XR', 'XL', 'YR', 'YL', 'PP', 'PQ', 'QP', 'QQ', 'RCircular', 'LCircular', 'Linear', 'Ptotal', 'Plinear', 'PFtotal', 'PFlinear', 'Pangle'] # # Usage: find desc for an index, e.g. cordesclist[corrtype] # find index for a desc, e.g. cordesclist.index(corrdesc) # # ms = casa_tools.ms() tb = casa_tools.table() print('CACHE') print(tb.showcache()) # Access the MS #################################### # try: # ms.open(msfile,nomodify=True) # except: # print "ERROR: failed to open ms tool on file "+msfile # exit(1) #################################### # print 'Getting scansummary from MS' # get the scan summary using ms.getscansummary method # mysc = ms.getscansummary() # Already open - uncomment to run getscansummary # scd = ms.getscansummary() # #nscans = len( mysc['summary'].keys() ) # nscans = len( scd.keys() ) # print 'Found '+str(nscans)+' scans' # # Find number of data description IDs with casa_tools.TableReader(msfile + '/DATA_DESCRIPTION') as table: ddspwarr=table.getcol("SPECTRAL_WINDOW_ID") ddpolarr=table.getcol("POLARIZATION_ID") ddspwlist = ddspwarr.tolist() ddpollist = ddpolarr.tolist() ndd = len(ddspwlist) # print 'Found '+str(ndd)+' DataDescription IDs' # # The SPECTRAL_WINDOW table with casa_tools.TableReader(msfile + '/SPECTRAL_WINDOW') as table: nchanarr=table.getcol("NUM_CHAN") spwnamearr=table.getcol("NAME") reffreqarr=table.getcol("REF_FREQUENCY") nspw = len(nchanarr) spwlookup = {} for isp in range(nspw): spwlookup[isp] = {} spwlookup[isp]['nchan'] = nchanarr[isp] spwlookup[isp]['name'] = str( spwnamearr[isp] ) spwlookup[isp]['reffreq'] = reffreqarr[isp] # print 'Extracted information for '+str(nspw)+' SpectralWindows' # # Now the polarizations (number of correlations in each pol id with casa_tools.TableReader(msfile + '/POLARIZATION') as table: ncorarr=table.getcol("NUM_CORR") # corr_type is in general variable shape, have to read row-by-row # or use getvarcol to return into dictionary, we will iterate manually npols = len(ncorarr) polindex = {} poldescr = {} for ip in range(npols): cort = table.getcol("CORR_TYPE", startrow=ip, nrow=1) (nct, nr) = cort.shape cortypes = [] cordescs = [] for ict in range(nct): cct = cort[ict][0] cde = cordesclist[cct] cortypes.append(cct) cordescs.append(cde) polindex[ip] = cortypes poldescr[ip] = cordescs # cortype is an array of npol, e.g. 5,6,7,8 is for RR,RL,LR,LL respectively # for alma this would be 9,10,11,12 for XX,XY,YX,YY respectively # cordesc are the strings associated with the types (enum for casa) # print 'Extracted information for '+str(npols)+' Polarization Setups' # # Build the DD index # ddindex = {} ncorlist=ncorarr.tolist() for idd in range(ndd): ddindex[idd] = {} isp = ddspwlist[idd] ddindex[idd]['spw'] = isp ddindex[idd]['spwname'] = spwlookup[isp]['name'] ddindex[idd]['nchan'] = spwlookup[isp]['nchan'] ddindex[idd]['reffreq'] = spwlookup[isp]['reffreq'] ipol = ddpollist[idd] ddindex[idd]['ipol'] = ipol ddindex[idd]['npol'] = ncorlist[ipol] ddindex[idd]['corrtype'] = polindex[ipol] ddindex[idd]['corrdesc'] = poldescr[ipol] # # Now get raw scan intents from STATE table with casa_tools.TableReader(msfile + '/STATE') as table: intentarr = table.getcol("OBS_MODE") subscanarr = table.getcol("SUB_SCAN") intentlist = intentarr.tolist() subscanlist = subscanarr.tolist() nstates = intentlist.__len__() # print 'Found '+str(nstates)+' StateIds' # # Now get FIELD table directions with casa_tools.TableReader(msfile + '/FIELD') as table: fnamearr = table.getcol("NAME") fpdirarr = table.getcol("PHASE_DIR") flist = fnamearr.tolist() nfields = len(flist) (nd1, nd2, npf) = fpdirarr.shape fielddict = {} for ifld in range(nfields): fielddict[ifld] = {} fielddict[ifld]['name'] = flist[ifld] # these are numpy.float64 fielddict[ifld]['rra'] = fpdirarr[0, 0, ifld] fielddict[ifld]['rdec'] = fpdirarr[1, 0, ifld] # # Now compile list of visibility times and info # # Extract times from the Main Table # Build lookup for DDs by scan_number timdict = {} ddlookup = {} ddscantimes = {} ntottimes = 0 with casa_tools.MSReader(msfile) as ms: for idd in range(ndd): # Select this DD (after reset if needed) if idd > 0: ms.selectinit(reset=True) ms.selectinit(idd) # recf = ms.getdata(["flag"]) # (nx,nc,ni) = recf['flag'].shape # get the times rect = ms.getdata(["time", "field_id", "scan_number"], ifraxis=True) nt = rect['time'].shape[0] ntottimes += nt print('Found {} times in DD={}'.format(nt, idd)) timdict[idd] = {} timdict[idd]['time'] = rect['time'] timdict[idd]['field_id'] = rect['field_id'] timdict[idd]['scan_number'] = rect['scan_number'] for it in range(nt): isc = rect['scan_number'][it] tim = rect['time'][it] if isc in ddlookup: if ddlookup[isc].count(idd)<1: ddlookup[isc].append(idd) if idd in ddscantimes[isc]: ddscantimes[isc][idd].append(tim) else: ddscantimes[isc][idd] = [tim] else: ddlookup[isc] = [idd] ddscantimes[isc] = {} ddscantimes[isc][idd] = [tim] # print 'Found total '+str(ntottimes)+' times' # ms.close() # compile a list of scan times # # scd = mysc['summary'] scanlist = [] scanindex = {} scl = list(scd.keys()) for sscan in scl: isc = int(sscan) scanlist.append(isc) scanindex[isc]=sscan scanlist.sort() nscans = len(scanlist) # print 'Found '+str(nscans)+' scans min='+str(min(scanlist))+' max='+str(max(scanlist)) scantimes = [] scandict = {} # Put DataDescription lookup into dictionary scandict['DataDescription'] = ddindex # Put Scan information in dictionary scandict['Scans'] = {} for isc in scanlist: sscan = scanindex[isc] # sub-scans, differentiated by StateId subs = list(scd[sscan].keys()) scan_start = -1. scan_end = -1. for ss in subs: bt = scd[sscan][ss]['BeginTime'] et = scd[sscan][ss]['EndTime'] if scan_start > 0.: if bt < scan_start: scan_start = bt else: scan_start = bt if scan_end > 0.: if et > scan_end: scan_end = et else: scan_end = et scan_mid = 0.5*(scan_start + scan_end) scan_int = scd[sscan]['0']['IntegrationTime'] scantimes.append(scan_mid) scandict['Scans'][isc] = {} scandict['Scans'][isc]['scan_start'] = scan_start scandict['Scans'][isc]['scan_end'] = scan_end scandict['Scans'][isc]['scan_mid'] = scan_mid scandict['Scans'][isc]['scan_int'] = scan_int ifld = scd[sscan]['0']['FieldId'] scandict['Scans'][isc]['field'] = ifld scandict['Scans'][isc]['rra'] = fielddict[ifld]['rra'] scandict['Scans'][isc]['rdec'] = fielddict[ifld]['rdec'] spws = scd[sscan]['0']['SpwIds'] scandict['Scans'][isc]['spw'] = spws.tolist() # state id of first sub-scan stateid = scd[sscan]['0']['StateId'] # get intents from STATE table intents = intentlist[stateid] # this is a string with comma-separated intents scandict['Scans'][isc]['intents'] = intents # DDs for this scan ddlist = ddlookup[isc] scandict['Scans'][isc]['dd'] = ddlist # number of polarizations for this list of dds ddnpollist = [] for idd in ddlist: npol = ddindex[idd]['npol'] ddnpollist.append(npol) scandict['Scans'][isc]['npol'] = ddnpollist # visibility times per dd in this scan # scandict['Scans'][isc]['times'] = {} for idd in ddlist: scandict['Scans'][isc]['times'][idd] = ddscantimes[isc][idd] mysize = scandict.__sizeof__() # print 'Size of scandict in memory is '+str(mysize)+' bytes' # print('CACHE END') # print(tb.showcache()) return scandict
[docs]class VLAScanHeuristics(object): def __init__(self, vis): self.vis = vis
[docs] def makescandict(self): """Run Steve's buildscans""" with casa_tools.MSReader(self.vis) as ms: self.scan_summary = ms.getscansummary() self.ms_summary = ms.summary() # self.scandict = buildscans(self.vis, self.scan_summary) # self.startdate=float(self.ms_summary['BeginTime']) # with casa_tools.TableReader(self.inputs.vis) as table: # self.scanNums = sorted(numpy.unique(table.getcol('SCAN_NUMBER'))) # These will be needed later in the pipeline self.gain_solint1 = {} self.gain_solint2 = {} self.shortsol1 = {} self.shortsol2 = {} self.longsolint = {} self.short_solint = {} self.new_gain_solint1 = {} self.ignorerefant = [] self.fluxscale_sources = [] self.fluxscale_flux_densities = [] self.fluxscale_spws = [] self.flagspw1 = '' self.flagspw1b = '' self.flagspw2 = '' """ Prep string listing of correlations from dictionary created by method buildscans For now, only use the parallel hands. Cross hands will be implemented later. """ # self.corrstring_list = self.scandict['DataDescription'][0]['corrdesc'] # self.removal_list = ['RL', 'LR', 'XY', 'YX'] # self.corrstring_list = list(set(self.corrstring_list).difference(set(self.removal_list))) # self.corrstring = string.join(self.corrstring_list,',') # Create dictionary of band names from spw ids # self.spw2band = self.convertspw2band() return True
[docs] def calibratorIntentsOld(self): """ # Identify scans and fields associated with different calibrator intents # NB: the scan intent definitions changed in the OPT on Feb 21, # 2012. So test on date: """ # tb = casa_tools.table() # print 'CAL INTENT CACHE 1:' # print tb.showcache() with casa_tools.TableReader(self.vis + '/SPECTRAL_WINDOW') as table: channels = table.getcol('NUM_CHAN') numSpws = len(channels) with casa_tools.MSReader(self.vis) as ms: self.ms_summary = ms.summary() startdate=float(self.ms_summary['BeginTime']) with casa_tools.TableReader(self.vis + '/STATE') as table: intents = table.getcol('OBS_MODE') self.bandpass_state_IDs = [] self.delay_state_IDs = [] self.flux_state_IDs = [] self.polarization_state_IDs = [] self.phase_state_IDs = [] self.amp_state_IDs = [] self.calibrator_state_IDs = [] self.pointing_state_IDs = [] # print 'CAL INTENT CACHE 2:' # print tb.showcache() if startdate <= 55978.50: for state_ID in range(0, len(intents)): self.state_intents = intents[state_ID].rsplit(',') for intent in range(0, len(self.state_intents)): self.scan_intent = self.state_intents[intent].rsplit('#')[0] self.subscan_intent = self.state_intents[intent].rsplit('#')[1] if self.scan_intent == 'CALIBRATE_BANDPASS': self.bandpass_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_DELAY': self.delay_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_AMPLI': self.flux_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_POLARIZATION': self.polarization_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_PHASE': self.phase_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_POINTING': self.pointing_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) # casa_tools.table.open(self.vis) if len(self.flux_state_IDs) == 0: # QA_msinfo='Fail' # logprint("ERROR: No flux density calibration scans found", logfileout='logs/msinfo.log') raise Exception("No flux density calibration scans found") else: self.flux_state_select_string = ('STATE_ID in [%s'%self.flux_state_IDs[0]) for state_ID in range(1, len(self.flux_state_IDs)): self.flux_state_select_string += (',%s')%self.flux_state_IDs[state_ID] self.flux_state_select_string += ']' # print 'CAL INTENT CACHE 3:' # print tb.showcache() with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.flux_state_select_string) self.flux_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.flux_scan_select_string = ','.join(["%s" % ii for ii in self.flux_scan_list]) # logprint ("Flux density calibrator(s) scans are " # +flux_scan_select_string, logfileout='logs/msinfo.log') self.flux_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.flux_field_select_string = ','.join(["%s" % ii for ii in self.flux_field_list]) # logprint ("Flux density calibrator(s) are fields " # +flux_field_select_string, logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 4:' # print tb.showcache() if len(self.bandpass_state_IDs) == 0: # logprint ("No bandpass calibration scans defined, using flux density calibrator(s)") self.bandpass_scan_select_string=self.flux_scan_select_string # logprint ("Bandpass calibrator(s) scans are " # +bandpass_scan_select_string, logfileout='logs/msinfo.log') self.bandpass_field_select_string=self.flux_field_select_string # logprint ("Bandpass calibrator(s) are fields " # +bandpass_field_select_string, logfileout='logs/msinfo.log') else: self.bandpass_state_select_string = ('STATE_ID in [%s'%self.bandpass_state_IDs[0]) for state_ID in range(1, len(self.bandpass_state_IDs)): self.bandpass_state_select_string += (',%s')%self.bandpass_state_IDs[state_ID] self.bandpass_state_select_string += ']' # print 'CAL INTENT CACHE 5:' # print tb.showcache() with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.bandpass_state_select_string) self.bandpass_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.bandpass_scan_select_string = ','.join(["%s" % ii for ii in self.bandpass_scan_list]) # logprint ("Bandpass calibrator(s) scans are " # +bandpass_scan_select_string, logfileout='logs/msinfo.log') self.bandpass_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.bandpass_field_select_string = ','.join(["%s" % ii for ii in self.bandpass_field_list]) # logprint ("Bandpass calibrator(s) are fields " # +bandpass_field_select_string, logfileout='logs/msinfo.log') if len(self.bandpass_field_list) > 1: # logprint ("WARNING: More than one field is defined as the bandpass calibrator.", # logfileout='logs/msinfo.log') # logprint ("WARNING: Models are required for all BP calibrators if multiple fields", # logfileout='logs/msinfo.log') # logprint ("WARNING: are to be used, not yet implemented; the pipeline will use", # logfileout='logs/msinfo.log') # logprint ("WARNING: only the first field.", logfileout='logs/msinfo.log') self.bandpass_field_select_string = str(self.bandpass_field_list[0]) subtable.close() # print 'CAL INTENT CACHE 6:' # print tb.showcache() if len(self.delay_state_IDs) == 0: # logprint ("No delay calibration scans defined, using bandpass calibrator") self.delay_scan_select_string = self.bandpass_scan_select_string # logprint ("Delay calibrator(s) scans are "+delay_scan_select_string, logfileout='logs/msinfo.log') self.delay_field_select_string = self.bandpass_field_select_string # logprint ("Delay calibrator(s) are fields "+delay_field_select_string, logfileout='logs/msinfo.log') else: self.delay_state_select_string = ('STATE_ID in [%s'%self.delay_state_IDs[0]) for state_ID in range(1, len(self.delay_state_IDs)): self.delay_state_select_string += (',%s') % self.delay_state_IDs[state_ID] self.delay_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.delay_state_select_string) self.delay_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.delay_scan_select_string = ','.join(["%s" % ii for ii in self.delay_scan_list]) # logprint ("Delay calibrator(s) scans are "+delay_scan_select_string, logfileout='logs/msinfo.log') self.delay_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.delay_field_select_string = ','.join(["%s" % ii for ii in self.delay_field_list]) # logprint ("Delay calibrator(s) are fields "+delay_field_select_string, # logfileout='logs/msinfo.log') if (len(self.delay_field_list) > 1): # logprint ("WARNING: More than one field is defined as the delay calibrator.", # logfileout='logs/msinfo.log') # logprint ("WARNING: Models are required for all delay calibrators if multiple fields", # logfileout='logs/msinfo.log') # logprint ("WARNING: are to be used, not yet implemented; the pipeline will use", # logfileout='logs/msinfo.log') # logprint ("WARNING: only the first field.", logfileout='logs/msinfo.log') self.delay_field_select_string = str(self.delay_field_list[0]) subtable.close() # print 'CAL INTENT CACHE 7:' # print tb.showcache() if len(self.polarization_state_IDs) == 0: # logprint ("No polarization calibration scans defined, no polarization calibration possible", # logfileout='logs/msinfo.log') self.polarization_scan_select_string='' self.polarization_field_select_string='' else: # logprint ("Warning: polarization calibration scans found, # but polarization calibration not yet implemented", logfileout='logs/msinfo.log') self.polarization_state_select_string = ('STATE_ID in [%s'%self.polarization_state_IDs[0]) for state_ID in range(1, len(self.polarization_state_IDs)): self.polarization_state_select_string += (',%s')%self.polarization_state_IDs[state_ID] self.polarization_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.polarization_state_select_string) self.polarization_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.polarization_scan_select_string = ','.join(["%s" % ii for ii in self.polarization_scan_list]) # logprint ("Polarization calibrator(s) scans are "+polarization_scan_select_string, # logfileout='logs/msinfo.log') self.polarization_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.polarization_field_select_string = ','.join(["%s" % ii for ii in self.polarization_field_list]) # logprint ("Polarization calibrator(s) are fields "+polarization_field_select_string, # logfileout='logs/msinfo.log' subtable.close() # print 'CAL INTENT CACHE 8:' # print tb.showcache() if len(self.phase_state_IDs) == 0: # QA_msinfo='Fail' # logprint("ERROR: No gain calibration scans found", logfileout='logs/msinfo.log') raise Exception("No gain calibration scans found") else: self.phase_state_select_string = ('STATE_ID in [%s'%self.phase_state_IDs[0]) for state_ID in range(1, len(self.phase_state_IDs)): self.phase_state_select_string += (',%s')%self.phase_state_IDs[state_ID] self.phase_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.phase_state_select_string) self.phase_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.phase_scan_select_string = ','.join(["%s" % ii for ii in self.phase_scan_list]) # logprint ("Phase calibrator(s) scans are "+phase_scan_select_string, # logfileout='logs/msinfo.log') self.phase_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.phase_field_select_string = ','.join(["%s" % ii for ii in self.phase_field_list]) # logprint ("Phase calibrator(s) are fields "+phase_field_select_string, # logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 9:' # print tb.showcache() # Find all calibrator scans and fields self.calibrator_state_select_string = ('STATE_ID in [%s'%self.calibrator_state_IDs[0]) for state_ID in range(1, len(self.calibrator_state_IDs)): self.calibrator_state_select_string += (',%s')%self.calibrator_state_IDs[state_ID] self.calibrator_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.calibrator_state_select_string) self.calibrator_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.calibrator_scan_select_string = ','.join(["%s" % ii for ii in self.calibrator_scan_list]) self.calibrator_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.calibrator_field_select_string = ','.join(["%s" % ii for ii in self.calibrator_field_list]) subtable.close() # print 'CAL INTENT CACHE 10:' # print tb.showcache() # casa_tools.table.close() else: for state_ID in range(0, len(intents)): self.state_intents = intents[state_ID].rsplit(',') for intent in range(0, len(self.state_intents)): self.scan_intent = self.state_intents[intent].rsplit('#')[0] self.subscan_intent = self.state_intents[intent].rsplit('#')[1] if self.scan_intent == 'CALIBRATE_BANDPASS': self.bandpass_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_DELAY': self.delay_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_FLUX': self.flux_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_POLARIZATION': self.polarization_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_AMPLI': self.amp_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_PHASE': self.phase_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) elif self.scan_intent == 'CALIBRATE_POINTING': self.pointing_state_IDs.append(state_ID) self.calibrator_state_IDs.append(state_ID) # casa_tools.table.open(self.vis) if len(self.flux_state_IDs) == 0: # QA_msinfo='Fail' # logprint("ERROR: No flux density calibration scans found", logfileout='logs/msinfo.log') raise Exception("No flux density calibration scans found") else: self.flux_state_select_string = ('STATE_ID in [%s'%self.flux_state_IDs[0]) for state_ID in range(1, len(self.flux_state_IDs)): self.flux_state_select_string += (',%s')%self.flux_state_IDs[state_ID] self.flux_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.flux_state_select_string) self.flux_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.flux_scan_select_string = ','.join(["%s" % ii for ii in self.flux_scan_list]) # logprint ("Flux density calibrator(s) scans are "+flux_scan_select_string, # logfileout='logs/msinfo.log') self.flux_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.flux_field_select_string = ','.join(["%s" % ii for ii in self.flux_field_list]) # logprint ("Flux density calibrator(s) are fields "+flux_field_select_string, # logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 11:' # print tb.showcache() if len(self.bandpass_state_IDs) == 0: # logprint ("No bandpass calibration scans defined, using flux density calibrator", # logfileout='logs/msinfo.log') self.bandpass_scan_select_string=self.flux_scan_select_string # logprint ("Bandpass calibrator(s) scans are "+bandpass_scan_select_string, # logfileout='logs/msinfo.log') self.bandpass_field_select_string=self.flux_field_select_string # logprint ("Bandpass calibrator(s) are fields "+bandpass_field_select_string, # logfileout='logs/msinfo.log') else: self.bandpass_state_select_string = ('STATE_ID in [%s'%self.bandpass_state_IDs[0]) for state_ID in range(1, len(self.bandpass_state_IDs)): self.bandpass_state_select_string += (',%s')%self.bandpass_state_IDs[state_ID] self.bandpass_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.bandpass_state_select_string) self.bandpass_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.bandpass_scan_select_string = ','.join(["%s" % ii for ii in self.bandpass_scan_list]) # logprint ("Bandpass calibrator(s) scans are "+bandpass_scan_select_string, # logfileout='logs/msinfo.log') self.bandpass_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.bandpass_field_select_string = ','.join(["%s" % ii for ii in self.bandpass_field_list]) # logprint ("Bandpass calibrator(s) are fields "+bandpass_field_select_string, # logfileout='logs/msinfo.log') if len(self.bandpass_field_list) > 1: # logprint ("WARNING: More than one field is defined as the bandpass calibrator.", # logfileout='logs/msinfo.log') # logprint ("WARNING: Models are required for all BP calibrators if multiple fields", # logfileout='logs/msinfo.log') # logprint ("WARNING: are to be used, not yet implemented; the pipeline will use", # logfileout='logs/msinfo.log') # logprint ("WARNING: only the first field.", logfileout='logs/msinfo.log') self.bandpass_field_select_string = str(self.bandpass_field_list[0]) subtable.close() # print 'CAL INTENT CACHE 12:' # print tb.showcache() if len(self.delay_state_IDs) == 0: # logprint ("No delay calibration scans defined, using bandpass calibrator", # logfileout='logs/msinfo.log') self.delay_scan_select_string=self.bandpass_scan_select_string # logprint ("Delay calibrator(s) scans are "+delay_scan_select_string, logfileout='logs/msinfo.log') self.delay_field_select_string=self.bandpass_field_select_string # logprint ("Delay calibrator(s) are fields "+delay_field_select_string, logfileout='logs/msinfo.log') else: self.delay_state_select_string = ('STATE_ID in [%s'%self.delay_state_IDs[0]) for state_ID in range(1, len(self.delay_state_IDs)): self.delay_state_select_string += (',%s') % self.delay_state_IDs[state_ID] self.delay_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.delay_state_select_string) self.delay_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.delay_scan_select_string = ','.join(["%s" % ii for ii in self.delay_scan_list]) # logprint ("Delay calibrator(s) scans are "+delay_scan_select_string, logfileout='logs/msinfo.log') self.delay_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.delay_field_select_string = ','.join(["%s" % ii for ii in self.delay_field_list]) # logprint ("Delay calibrator(s) are fields "+delay_field_select_string, # logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 13:' # print tb.showcache() if len(self.polarization_state_IDs) == 0: # logprint ("No polarization calibration scans defined, no polarization calibration possible", # logfileout='logs/msinfo.log') self.polarization_scan_select_string='' self.polarization_field_select_string='' else: # logprint ("Warning: polarization calibration scans found, # but polarization calibration not yet implemented", logfileout='logs/msinfo.log') self.polarization_state_select_string = ('STATE_ID in [%s' % self.polarization_state_IDs[0]) for state_ID in range(1, len(self.polarization_state_IDs)): self.polarization_state_select_string += (',%s') % self.polarization_state_IDs[state_ID] self.polarization_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.polarization_state_select_string) self.polarization_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.polarization_scan_select_string = ','.join(["%s" % ii for ii in self.polarization_scan_list]) # logprint ("Polarization calibrator(s) scans are "+polarization_scan_select_string, # logfileout='logs/msinfo.log') self.polarization_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.polarization_field_select_string = ','.join(["%s" % ii for ii in self.polarization_field_list]) # logprint ("Polarization calibrator(s) are fields "+polarization_field_select_string, # logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 14:' # print tb.showcache() if len(self.phase_state_IDs) == 0: # QA_msinfo='Fail' # logprint("ERROR: No gain calibration scans found", logfileout='logs/msinfo.log') raise Exception("No gain calibration scans found") else: self.phase_state_select_string = ('STATE_ID in [%s'%self.phase_state_IDs[0]) for state_ID in range(1, len(self.phase_state_IDs)): self.phase_state_select_string += (',%s')%self.phase_state_IDs[state_ID] self.phase_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.phase_state_select_string) self.phase_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.phase_scan_select_string = ','.join(["%s" % ii for ii in self.phase_scan_list]) # logprint ("Phase calibrator(s) scans are "+phase_scan_select_string, logfileout='logs/msinfo.log') self.phase_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.phase_field_select_string = ','.join(["%s" % ii for ii in self.phase_field_list]) # logprint ("Phase calibrator(s) are fields "+phase_field_select_string, # logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 15:' # print tb.showcache() if len(self.amp_state_IDs) == 0: # logprint ("No amplitude calibration scans defined, will use phase calibrator", # logfileout='logs/msinfo.log') self.amp_scan_select_string=self.phase_scan_select_string # logprint ("Amplitude calibrator(s) scans are "+amp_scan_select_string, logfileout='logs/msinfo.log') self.amp_field_select_string=self.phase_scan_select_string # logprint ("Amplitude calibrator(s) are fields "+amp_field_select_string, logfileout='logs/msinfo.log') else: self.amp_state_select_string = ('STATE_ID in [%s'%self.amp_state_IDs[0]) for state_ID in range(1, len(self.amp_state_IDs)): self.amp_state_select_string += (',%s') % self.amp_state_IDs[state_ID] self.amp_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.amp_state_select_string) self.amp_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.amp_scan_select_string = ','.join(["%s" % ii for ii in self.amp_scan_list]) # logprint ("Amplitude calibrator(s) scans are "+amp_scan_select_string, # logfileout='logs/msinfo.log') self.amp_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.amp_field_select_string = ','.join(["%s" % ii for ii in self.amp_field_list]) # logprint ("Amplitude calibrator(s) are fields "+amp_field_select_string, # logfileout='logs/msinfo.log') subtable.close() # print 'CAL INTENT CACHE 16:' # print tb.showcache() # Find all calibrator scans and fields self.calibrator_state_select_string = ('STATE_ID in [%s'%self.calibrator_state_IDs[0]) for state_ID in range(1, len(self.calibrator_state_IDs)): self.calibrator_state_select_string += (',%s')%self.calibrator_state_IDs[state_ID] self.calibrator_state_select_string += ']' with casa_tools.TableReader(self.vis) as table: subtable = table.query(self.calibrator_state_select_string) self.calibrator_scan_list = list(numpy.unique(subtable.getcol('SCAN_NUMBER'))) self.calibrator_scan_select_string = ','.join(["%s" % ii for ii in self.calibrator_scan_list]) self.calibrator_field_list = list(numpy.unique(subtable.getcol('FIELD_ID'))) self.calibrator_field_select_string = ','.join(["%s" % ii for ii in self.calibrator_field_list]) subtable.close() # print 'CAL INTENT CACHE 17:' # print tb.showcache() # casa_tools.table.close() # If there are any pointing state IDs, subtract 2 from the number of # science spws -- needed for QA scores if len(self.pointing_state_IDs)>0: self.numSpws2 = numSpws - 2 else: self.numSpws2 = numSpws if self.delay_scan_select_string == self.bandpass_scan_select_string: self.testgainscans = self.bandpass_scan_select_string else: self.testgainscans = self.bandpass_scan_select_string + ',' + self.delay_scan_select_string self.checkflagfields = '' if self.bandpass_field_select_string == self.delay_field_select_string: self.checkflagfields = self.bandpass_field_select_string else: self.checkflagfields = (self.bandpass_field_select_string + ',' + self.delay_field_select_string) return True
[docs] def calibratorIntents(self): """ # Identify scans and fields associated with different calibrator intents # NB: the scan intent definitions changed in the OPT on Feb 21, # 2012. So test on date: # Test Implementation: JSK April 11, 2016 """ def buildSelectionString(selectionList): return ','.join(["%s" % item for item in selectionList]) with casa_tools.MSMDReader(self.vis) as msmd: # We used to use CALIBRATE_AMPLI rather than FLUX # Note that in the current epoch we do not use the # CALIBRATE_AMPLI intent for anything. # There is an implicit assumption here that we only have one # observation in the MS # Changed April 2018 so that all flux scans and fields require FLUX, # even prior to 2013. if casa_tools.quanta.le(msmd.timerangeforobs(0)['begin']['m0'], casa_tools.quanta.quantity("2012/02/21 12:00:00")): self.flux_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE_FLUX*")) self.flux_field_select_string = \ buildSelectionString(msmd.fieldsforintent("CALIBRATE_FLUX*")) else: self.flux_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE_FLUX*")) self.flux_field_select_string = \ buildSelectionString(msmd.fieldsforintent("CALIBRATE_FLUX*")) if (self.flux_field_select_string == ''): LOG.warn("No flux density calibration fields found") # Bandpass Cal Intent self.bandpass_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE_BANDPASS*")) bpfieldlist = msmd.fieldsforintent("CALIBRATE_BANDPASS*") if len(bpfieldlist) > 1: self.bandpass_field_select_string = \ buildSelectionString([bpfieldlist[0]]) LOG.warn("More than one field is defined as the bandpass calibrator.") LOG.warn(" Models are required for all BP calibrators if multiple fields ") LOG.warn(" are to be used, not yet implemented; the pipeline will use ") LOG.warn(" only the first field.") else: self.bandpass_field_select_string = \ buildSelectionString(bpfieldlist) if (self.bandpass_scan_select_string == '' or self.bandpass_field_select_string == ''): # Default to using the flux scan for bandpass self.bandpass_scan_select_string = self.flux_scan_select_string self.bandpass_field_select_string = self.flux_field_select_string # Delay Cal Intent self.delay_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE_DELAY*")) delayfieldlist = msmd.fieldsforintent("CALIBRATE_DELAY*") if len(delayfieldlist) > 1: self.delay_field_select_string = \ buildSelectionString([delayfieldlist[0]]) LOG.warn("More than one field is defined as the delay calibrator.") LOG.warn(" The pipeline will use only the first field.") else: self.delay_field_select_string = \ buildSelectionString(delayfieldlist) if (self.delay_scan_select_string == '' or self.delay_field_select_string == ''): # Default to using the bandpass for the delay self.delay_scan_select_string = self.bandpass_scan_select_string self.delay_field_select_string = self.bandpass_field_select_string # Polarization Cal Intent self.polarization_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE_POLARIZATION*")) self.polarization_field_select_string =\ buildSelectionString(msmd.fieldsforintent("CALIBRATE_POLARIZATION*")) # Phase Cal Intent self.phase_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE_PHASE*")) self.phase_field_select_string = \ buildSelectionString(msmd.fieldsforintent("CALIBRATE_PHASE*")) if (self.phase_scan_select_string == '' or self.phase_field_select_string == ''): LOG.warn("No gain calibration scans found") # Find all calibrator scans and fields self.calibrator_scan_select_string = \ buildSelectionString(msmd.scansforintent("CALIBRATE*")) self.calibrator_field_select_string = \ buildSelectionString(msmd.fieldsforintent("CALIBRATE*")) # JSK: Modifying the heuristic for dealing with the number of # science SPWs after discussion with Claire 4/12/2016. # New Heuristic is: from numSpws2 subtract the number of spws that # only appear in pointing scans. # # Here is the Old hueristic # If there are any pointing state IDs, subtract 2 from the number of # science spws -- needed for QA scores # if (len(self.pointing_state_IDs)>0): # self.numSpws2 = numSpws - 2 # else: # self.numSpws2 = numSpws self.numSpws2 = msmd.nspw() obsTargetSpws = msmd.spwsforintent("OBSERVE_TARGET*").tolist() pointingSpws = msmd.spwsforintent("CALIBRATE_POINTING*").tolist() for spw in pointingSpws: if not obsTargetSpws.count(spw): self.numSpws2 -= 1 # Here we pass through a set construct to get the unique union. self.testgainscans= buildSelectionString(set (msmd.scansforintent("CALIBRATE_BANDPASS*").tolist() + msmd.scansforintent("CALIBRATE_DELAY*").tolist())) self.checkflagfields= buildSelectionString(set (msmd.fieldsforintent("CALIBRATE_BANDPASS*").tolist() + msmd.fieldsforintent("CALIBRATE_DELAY*").tolist())) return True
[docs] def find_3C84(self, positions): MAX_SEPARATION = 60*2.0e-5 position_3C84 = casa_tools.measures.direction('j2000', '3h19m48.160', '41d30m42.106') fields_3C84 = [] for ii in range(0, len(positions)): position = casa_tools.measures.direction('j2000', str(positions[ii][0]) + 'rad', str(positions[ii][1]) + 'rad') separation = casa_tools.measures.separation(position, position_3C84)['value'] * math.pi / 180.0 if separation < MAX_SEPARATION: fields_3C84.append(ii) return fields_3C84
[docs] def determine3C84(self): """ #Determine if 3C84 was used as a bandpass or delay calibrator """ self.positions = [] with casa_tools.TableReader(self.vis + '/FIELD') as table: self.field_positions = table.getcol('PHASE_DIR') for ii in range(0, len(self.field_positions[0][0])): self.positions.append([self.field_positions[0][0][ii], self.field_positions[1][0][ii]]) self.fields_3C84 = self.find_3C84(self.positions) self.cal3C84_d = False self.cal3C84_bp = False # uvrange3C84 = '0~1800klambda' self.uvrange3C84 = '' if self.fields_3C84 != []: for field_int in self.fields_3C84: if str(field_int) in self.delay_field_select_string: self.cal3C84_d = True # logprint("WARNING: 3C84 was observed as a delay calibrator, uvrange limits may be used", # logfileout='logs/msinfo.log') if str(field_int) in self.bandpass_field_select_string: self.cal3C84_bp = True # logprint("WARNING: 3C84 was observed as a BP calibrator, uvrange limits may be used", # logfileout='logs/msinfo.log') if (self.cal3C84_d == True) or (self.cal3C84_bp == True): self.cal3C84 = True else: self.cal3C84 = False return True
[docs]def testCalibratorIntents(vis): # This is a temporary test program to see if the two methods of generating # intents yield the same answers. # To use: # from pipeline.hifv.heuristics.vlascanheuristics import testCalibratorIntents # testCalibratorIntents(<Name of MS>) print("Testing Comparison of: {}".format(vis)) origObj = VLAScanHeuristics(vis) newObj = VLAScanHeuristics(vis) exceptionThrown = False try: start = datetime.datetime.now() origObj.calibratorIntentsOld() print('origObj: {}'.format(datetime.datetime.now()-start)) except Exception as e: print(e) exceptionThrown = True try: start = datetime.datetime.now() newObj.calibratorIntents() print('newObj: {}'.format(datetime.datetime.now()-start)) except Exception as e: print(e) exceptionThrown = True # Now do the comparison: if origObj.flux_scan_select_string != newObj.flux_scan_select_string: print("flux_scan_select_strings Differ:") print("\tOrig: {}".format(origObj.flux_scan_select_string)) print("\tNew: {}".format(newObj.flux_scan_select_string)) if origObj.flux_field_select_string != newObj.flux_field_select_string: print("flux_field_select_strings Differ:") print("\tOrig: {}".format(origObj.flux_field_select_string)) print("\tNew: {}".format(newObj.flux_field_select_string)) if origObj.bandpass_scan_select_string != newObj.bandpass_scan_select_string: print("bandpass_scan_select_strings Differ:") print("\tOrig: {}".format(origObj.bandpass_scan_select_string)) print("\tNew: {}".format(newObj.bandpass_scan_select_string)) if origObj.bandpass_field_select_string != newObj.bandpass_field_select_string: print("bandpass_field_select_strings Differ:") print("\tOrig: {}".format(origObj.bandpass_field_select_string)) print("\tNew: {}".format(newObj.bandpass_field_select_string)) if origObj.delay_scan_select_string != newObj.delay_scan_select_string: print("delay_scan_select_strings Differ:") print("\tOrig: {}".format(origObj.delay_scan_select_string)) print("\tNew: {}".format(newObj.delay_scan_select_string)) if origObj.delay_field_select_string != newObj.delay_field_select_string: print("delay_field_select_strings Differ:") print("\tOrig: {}".format(origObj.delay_field_select_string)) print("\tNew: {}".format(newObj.delay_field_select_string)) if origObj.polarization_scan_select_string != newObj.polarization_scan_select_string: print("polarization_scan_select_strings Differ:") print("\tOrig: {}".format(origObj.polarization_scan_select_string)) print("\tNew: {}".format(newObj.polarization_scan_select_string)) if origObj.polarization_field_select_string != newObj.polarization_field_select_string: print("polarization_field_select_strings Differ:") print("\tOrig: {}".format(origObj.polarization_field_select_string)) print("\tNew: {}".format(newObj.polarization_field_select_string)) if origObj.phase_scan_select_string != newObj.phase_scan_select_string: print("phase_scan_select_strings Differ:") print("\tOrig: {}".format(origObj.phase_scan_select_string)) print("\tNew: {}".format(newObj.phase_scan_select_string)) if origObj.phase_field_select_string != newObj.phase_field_select_string: print("phase_field_select_strings Differ:") print("\tOrig: {}".format(origObj.phase_field_select_string)) print("\tNew: {}".format(newObj.phase_field_select_string)) if origObj.calibrator_scan_select_string != newObj.calibrator_scan_select_string: print("calibrator_scan_select_strings Differ:") print("\tOrig: {}".format(origObj.calibrator_scan_select_string)) print("\tNew: {}".format(newObj.calibrator_scan_select_string)) if origObj.calibrator_field_select_string != newObj.calibrator_field_select_string: print("calibrator_field_select_strings Differ:") print("\tOrig: {}".format(origObj.calibrator_field_select_string)) print("\tNew: {}".format(newObj.calibrator_field_select_string)) if origObj.testgainscans != newObj.testgainscans: print("testgainscanss Differ:") print("\tOrig: {}".format(origObj.testgainscans)) print("\tNew: {}".format(newObj.testgainscans)) if origObj.checkflagfields != newObj.checkflagfields: print("checkflagfieldss Differ:") print("\tOrig: {}".format(origObj.checkflagfields)) print("\tNew: {}".format(newObj.checkflagfields)) if origObj.numSpws2 != newObj.numSpws2: print("numSpws2 Differ:") print("\tOrig: {}".format(origObj.numSpws2)) print("\tNew: {}".format(newObj.numSpws2))