def get_image_sizes(self, cellsize_highres_deg=None, cellsize_lowres_deg=None, fieldsize_highres=2.5, fieldsize_lowres=6.5): """ Sets sizes for initsubtract images The image sizes are scaled from the mean primary-beam FWHM. For the high-res image, we use 2.5 * FWHM; for low-res, we use 6.5 * FHWM. Parameters ---------- cellsize_highres_deg : float, optional cellsize for the high-res images in deg cellsize_lowres_deg : float, optional cellsize for the low-res images in deg fieldsize_highres : float, optional How many FWHM's shall the high-res images be. fieldsize_lowres : float, optional How many FWHM's shall the low-res images be. """ if cellsize_highres_deg: self.cellsize_highres_deg = cellsize_highres_deg if cellsize_lowres_deg: self.cellsize_lowres_deg = cellsize_lowres_deg if not hasattr(self, 'mean_el_rad'): for MS_id in xrange(self.numMS): # Add (virtual) elevation column to MS try: pt.addDerivedMSCal(self.files[MS_id]) except RuntimeError: # RuntimeError indicates column already exists pass # calculate mean elevation tab = pt.table(self.files[MS_id], ack=False) if MS_id == 0: global_el_values = tab.getcol('AZEL1', rowincr=10000)[:, 1] else: global_el_values = np.hstack( (global_el_values, tab.getcol('AZEL1', rowincr=10000)[:, 1])) tab.close() # Remove (virtual) elevation column from MS pt.removeDerivedMSCal(self.files[MS_id]) self.mean_el_rad = np.mean(global_el_values) # Calculate mean FOV sec_el = 1.0 / np.sin(self.mean_el_rad) self.fwhm_deg = 1.1 * ( (3.0e8 / self.freq) / self.diam) * 180. / np.pi * sec_el self.imsize_high_res = self.get_optimum_size( self.fwhm_deg / self.cellsize_highres_deg * fieldsize_highres) self.imsize_low_res = self.get_optimum_size( self.fwhm_deg / self.cellsize_lowres_deg * fieldsize_lowres) return (self.imsize_high_res, self.imsize_low_res)
def get_image_sizes(self, cellsize_highres_deg=None, cellsize_lowres_deg=None, fieldsize_highres=2.5, fieldsize_lowres=6.5): """ Sets sizes for initsubtract images The image sizes are scaled from the mean primary-beam FWHM. For the high-res image, we use 2.5 * FWHM; for low-res, we use 6.5 * FHWM. Parameters ---------- cellsize_highres_deg : float, optional cellsize for the high-res images in deg cellsize_lowres_deg : float, optional cellsize for the low-res images in deg fieldsize_highres : float, optional How many FWHM's shall the high-res images be. fieldsize_lowres : float, optional How many FWHM's shall the low-res images be. """ if cellsize_highres_deg: self.cellsize_highres_deg = cellsize_highres_deg if cellsize_lowres_deg: self.cellsize_lowres_deg = cellsize_lowres_deg if not hasattr(self, 'mean_el_rad'): for MS_id in xrange(self.numMS): # Add (virtual) elevation column to MS try: pt.addDerivedMSCal(self.files[MS_id]) except RuntimeError: # RuntimeError indicates column already exists pass # calculate mean elevation tab = pt.table(self.files[MS_id], ack=False) if MS_id == 0: global_el_values = tab.getcol('AZEL1', rowincr=10000)[:, 1] else: global_el_values = np.hstack( (global_el_values, tab.getcol('AZEL1', rowincr=10000)[:, 1]) ) tab.close() # Remove (virtual) elevation column from MS pt.removeDerivedMSCal(self.files[MS_id]) self.mean_el_rad = np.mean(global_el_values) # Calculate mean FOV sec_el = 1.0 / np.sin(self.mean_el_rad) self.fwhm_deg = 1.1 * ((3.0e8 / self.freq) / self.diam) * 180. / np.pi * sec_el self.imsize_high_res = self.get_optimum_size(self.fwhm_deg /self.cellsize_highres_deg * fieldsize_highres) self.imsize_low_res = self.get_optimum_size(self.fwhm_deg /self.cellsize_lowres_deg * fieldsize_lowres) return (self.imsize_high_res, self.imsize_low_res)
def main(options): global keepPlotting keepPlotting = True debug = options.debug inputMS = glob.glob(options.inms) if inputMS == '': print 'Error: You must specify a MS name.' print ' Use "uvplot.py -h" to get help.' return if options.inms.endswith('/'): options.inms = options.inms[:-1] inputMSbasename = options.inms.split('/')[-1] if inputMSbasename == '': # The user has not specified the full path of the MS inputMSbasename = options.inms device = options.device if device=='?': ppgplot.pgldev() return xaxis = options.xaxis if xaxis == 'ha': print 'Adding derived columns to allow plotting hour angle...' try: pt.addDerivedMSCal(inputMS) except: print 'Failed, trying to remove and add columns...' try: pt.removeDerivedMSCal(inputMS) pt.addDerivedMSCal(inputMS) except: print 'That failed too... plotting HA seems to not be possible.' return yaxis = options.yaxis column = options.column nx, ny = options.nxy.split(',') axlimits = options.axlimits.split(',') if len(axlimits) == 4: xmin,xmax,ymin,ymax = axlimits else: print 'Error: You must specify four axis limits' return showFlags = options.flag flagCol = options.colflag showAutocorr = options.autocorr showStats = options.statistics timeslots = options.timeslots.split(',') if len(timeslots) != 2: print 'Error: Timeslots format is start,end' return for i in range(len(timeslots)): timeslots[i] = int(timeslots[i]) antToPlotSpl = options.antennas.split(',') antToPlot = [] for i in range(len(antToPlotSpl)): tmpspl = antToPlotSpl[i].split('..') if len(tmpspl) == 1: antToPlot.append(int(antToPlotSpl[i])) elif len(tmpspl) == 2: for j in range(int(tmpspl[0]),int(tmpspl[1])+1): antToPlot.append(j) else: print 'Error: Could not understand antenna list.' return polarizations = options.polar.split(',') for i in range(len(polarizations)): polarizations[i] = int(polarizations[i]) convertStokes = options.stokes operation = options.operation if operation != '': operation = int(operation) if convertStokes: print 'Error: Stokes conversion is not compatible with special operations' return channels = options.channels.split(',') if len(channels) != 2: print 'Error: Channels format is start,end' return for i in range(len(channels)): channels[i] = int(channels[i]) if channels[1] == -1: channels[1] = None # last element even if there is only one else: channels[1] += 1 queryMode = options.query doUnwrap = options.wrap if not queryMode: # open the graphics device, use the right number of panels ppgplot.pgbeg(device, int(nx), int(ny)) # set the font size ppgplot.pgsch(1.5) ppgplot.pgvstd() # open the main table and print some info about the MS t = pt.table(inputMS, readonly=True, ack=False) firstTime = t.query(sortlist='TIME',columns='TIME',limit=1).getcell("TIME", 0) lastTime = t.query(sortlist='TIME',columns='TIME',offset=t.nrows()-1).getcell("TIME", 0) intTime = t.getcell("INTERVAL", 0) print 'Integration time:\t%f sec' % (intTime) nTimeslots = (lastTime - firstTime) / intTime if timeslots[1] == -1: timeslots[1] = nTimeslots else: timeslots[1] += 1 print 'Number of timeslots:\t%d' % (nTimeslots) # open the antenna and spectral window subtables tant = pt.table(t.getkeyword('ANTENNA'), readonly=True, ack=False) tsp = pt.table(t.getkeyword('SPECTRAL_WINDOW'), readonly=True, ack=False) numChannels = len(tsp.getcell('CHAN_FREQ',0)) print 'Number of channels:\t%d' % (numChannels) print 'Reference frequency:\t%5.2f MHz' % (tsp.getcell('REF_FREQUENCY',0)/1.e6) # Station names antList = tant.getcol('NAME') if len(antToPlot)==1 and antToPlot[0]==-1: antToPlot = range(len(antList)) print 'Station list (only starred stations will be plotted):' for i in range(len(antList)): star = ' ' if i in antToPlot: star = '*' print '%s %2d\t%s' % (star, i, antList[i]) # Bail if we're in query mode if queryMode: return # select by time from the beginning, and only use specified antennas tsel = t.query('TIME >= %f AND TIME <= %f AND ANTENNA1 IN %s AND ANTENNA2 IN %s' % (firstTime+timeslots[0]*intTime,firstTime+timeslots[1]*intTime,str(antToPlot),str(antToPlot))) # values to use for each polarization plotColors = [1,2,3,4] labXPositions = [0.35,0.45,0.55,0.65] labYPositions = [1.0,1.0,1.0,1.0] if convertStokes: polLabels = ['I','Q','U','V'] else: polLabels = ['XX','XY','YX','YY'] # define nicely written axis labels axisLabels = {'time': 'Time', 'ha': 'Hour angle', 'chan': 'Channel', 'freq': 'Frequency [MHz]', 'amp': 'Visibility amplitude', 'real': 'Real part of visibility', 'imag': 'Imaginary part of visibility', 'phase': 'Visibility phase [radians]'} # Now we loop through the baselines ppgplot.pgpage() for tpart in tsel.iter(["ANTENNA1","ANTENNA2"]): if not keepPlotting: return ant1 = tpart.getcell("ANTENNA1", 0) ant2 = tpart.getcell("ANTENNA2", 0) if ant1 not in antToPlot or ant2 not in antToPlot: continue if ant1 == ant2: if not showAutocorr: continue # Get the values to plot, strategy depends on axis type if xaxis == 'time' or xaxis == 'ha': xaxisvals = getXAxisVals(tpart, xaxis, channels) yaxisvals = getYAxisVals(tpart, yaxis, column, operation, showFlags, flagCol, channels, doUnwrap, convertStokes) else: xaxisvals = getXAxisVals(tsp, xaxis, channels) yaxisvals = getYAxisVals(tpart, yaxis, column, operation, showFlags, flagCol, channels, doUnwrap, convertStokes, xaxistype=1) if xaxisvals == None: # This baseline must be empty, go to next one print 'No good data on baseline %s - %s' % (antList[ant1],antList[ant2]) continue if debug: print xaxisvals.shape print yaxisvals.shape for r in range(len(xaxisvals)): print '%s'%yaxisvals[r] if len(xaxisvals) != len(yaxisvals): # something is wrong print 'Error: X and Y axis types incompatible' return # Plot the data, each polarization in a different color ppgplot.pgsci(1) if xmin == '': minx = xaxisvals.min() else: minx = float(xmin) if xmax == '': maxx = xaxisvals.max() else: maxx = float(xmax) if ymin == '': miny = yaxisvals.min() if numpy.ma.getmaskarray(yaxisvals.min()): print 'All data flagged on baseline %s - %s' % (antList[ant1],antList[ant2]) continue else: miny = float(ymin) if ymax == '': maxy = yaxisvals.max() else: maxy = float(ymax) if minx == maxx: minx -= 1.0 maxx += 1.0 else: diffx = maxx - minx minx -= 0.02*diffx maxx += 0.02*diffx if miny == maxy: miny -= 1.0 maxy += 1.0 else: diffy = maxy - miny miny -= 0.02*diffy maxy += 0.02*diffy #ppgplot.pgpage() ppgplot.pgswin(minx,maxx,miny,maxy) if xaxis == 'time' or xaxis == 'ha': ppgplot.pgtbox('ZHOBCNST',0.0,0,'BCNST',0.0,0) else: ppgplot.pgbox('BCNST',0.0,0,'BCNST',0.0,0) #ppgplot.pglab(axisLabels[xaxis], axisLabels[yaxis], '%s - %s'%(antList[ant1],antList[ant2])) #ppgplot.pgmtxt('T', 3.0, 0.5, 0.5, inputMSbasename) ppgplot.pglab(axisLabels[xaxis], axisLabels[yaxis], inputMSbasename + '(' + getDataDescription(column) + '): %s - %s'%(antList[ant1],antList[ant2])) if operation != 0: # some operations is defined if operation == 1: label = 'XX-YY' elif operation == 2: label = 'XY.YX*' else: print 'Special operation not defined' return ppgplot.pgsci(plotColors[0]) tmpvals = yaxisvals print 'Baseline',antList[ant1],'-',antList[ant2],': Plotting',len(tmpvals[~tmpvals.mask]),'points of ' + label ppgplot.pgpt(xaxisvals[~tmpvals.mask], tmpvals[~tmpvals.mask], 1) addInfo(showStats, tmpvals[~tmpvals.mask], label, labXPositions[1], labYPositions[1]) else: for j in polarizations: ppgplot.pgsci(plotColors[j]) tmpvals = yaxisvals[:,j] if j == polarizations[0]: print 'Baseline',antList[ant1],'-',antList[ant2],': Plotting',len(tmpvals[~tmpvals.mask]),'points per polarization' ppgplot.pgpt(xaxisvals[~tmpvals.mask], tmpvals[~tmpvals.mask], 1) addInfo(showStats, tmpvals[~tmpvals.mask], polLabels[j], labXPositions[j], labYPositions[j]) ppgplot.pgpage() # Close the PGPLOT device ppgplot.pgclos() if xaxis=='ha': print 'Removing derived columns...' pt.removeDerivedMSCal(inputMS)
def __init__(self, MSfiles, factor_working_dir, dirindparmdb, skymodel_dirindep=None, local_dir=None, test_run=False): self.files = MSfiles self.msnames = [ MS.split('/')[-1] for MS in self.files ] self.working_dir = factor_working_dir self.dirindparmdbs = [ os.path.join(MS, dirindparmdb) for MS in self.files ] self.skymodel_dirindep = skymodel_dirindep self.numMS = len(self.files) # Get the frequency info and set name sw = pt.table(self.files[0]+'::SPECTRAL_WINDOW', ack=False) self.freq = sw.col('REF_FREQUENCY')[0] self.nchan = sw.col('NUM_CHAN')[0] self.chan_freqs_hz = sw.col('CHAN_FREQ')[0] self.chan_width_hz = sw.col('CHAN_WIDTH')[0][0] sw.close() self.name = 'Band_{0:.2f}MHz'.format(self.freq/1e6) self.log = logging.getLogger('factor:{}'.format(self.name)) self.log.debug('Band name is {}'.format(self.name)) self.chunks_dir = os.path.join(factor_working_dir, 'chunks', self.name) # Do some checks self.check_freqs() self.check_parmdb() # Get the field RA and Dec obs = pt.table(self.files[0]+'::FIELD', ack=False) self.ra = np.degrees(float(obs.col('REFERENCE_DIR')[0][0][0])) if self.ra < 0.: self.ra = 360.0 + (self.ra) self.dec = np.degrees(float(obs.col('REFERENCE_DIR')[0][0][1])) obs.close() # Get the station diameter ant = pt.table(self.files[0]+'::ANTENNA', ack=False) self.diam = float(ant.col('DISH_DIAMETER')[0]) ant.close() # Find mean elevation and FOV for MS_id in xrange(self.numMS): # Add (virtual) elevation column to MS try: pt.addDerivedMSCal(self.files[MS_id]) except RuntimeError: # RuntimeError indicates column already exists pass # Calculate mean elevation tab = pt.table(self.files[MS_id], ack=False) if MS_id == 0: global_el_values = tab.getcol('AZEL1', rowincr=10000)[:, 1] else: global_el_values = np.hstack( (global_el_values, tab.getcol('AZEL1', rowincr=10000)[:, 1]) ) tab.close() # Remove (virtual) elevation column from MS pt.removeDerivedMSCal(self.files[MS_id]) self.mean_el_rad = np.mean(global_el_values) sec_el = 1.0 / np.sin(self.mean_el_rad) self.fwhm_deg = 1.1 * ((3.0e8 / self.freq) / self.diam) * 180. / np.pi * sec_el # Check for SUBTRACTED_DATA_ALL column in original datasets self.has_sub_data = True self.has_sub_data_new = False for MSid in xrange(self.numMS): tab = pt.table(self.files[MSid], ack=False) if not 'SUBTRACTED_DATA_ALL' in tab.colnames(): self.log.error('SUBTRACTED_DATA_ALL column not found in file ' '{}'.format(self.files[MSid])) self.has_sub_data = False tab.close() if not self.has_sub_data: self.log.info('Exiting...') sys.exit(1) # cut input files into chunks if needed chunksize = 2400. # in seconds -> 40min self.chunk_input_files(chunksize, dirindparmdb, local_dir=local_dir, test_run=test_run) # Calculate times and number of samples self.sumsamples = 0 self.minSamplesPerFile = 4294967295 # If LOFAR lasts that many seconds then I buy you a beer. self.starttime = np.finfo('d').max self.endtime = 0. for MSid in xrange(self.numMS): tab = pt.table(self.files[MSid], ack=False) self.starttime = min(self.starttime,np.min(tab.getcol('TIME'))) self.endtime = max(self.endtime,np.min(tab.getcol('TIME'))) for t2 in tab.iter(["ANTENNA1","ANTENNA2"]): if (t2.getcell('ANTENNA1',0)) < (t2.getcell('ANTENNA2',0)): self.timepersample = t2.col('TIME')[1] - t2.col('TIME')[0] numsamples = t2.nrows() self.sumsamples += numsamples self.minSamplesPerFile = min(self.minSamplesPerFile,numsamples) break tab.close() self.log.debug("Using {0} files.".format(len(self.files))) if skymodel_dirindep != None: self.log.debug("Using Skymodel: {}".format(os.path.basename(skymodel_dirindep)))
def __init__(self, MSfiles, factor_working_dir, dirindparmdb, skymodel_dirindep=None, local_dir=None, test_run=False): self.files = MSfiles self.msnames = [MS.split('/')[-1] for MS in self.files] self.working_dir = factor_working_dir self.dirindparmdbs = [ os.path.join(MS, dirindparmdb) for MS in self.files ] self.skymodel_dirindep = skymodel_dirindep self.numMS = len(self.files) # Get the frequency info and set name sw = pt.table(self.files[0] + '::SPECTRAL_WINDOW', ack=False) self.freq = sw.col('REF_FREQUENCY')[0] self.nchan = sw.col('NUM_CHAN')[0] self.chan_freqs_hz = sw.col('CHAN_FREQ')[0] self.chan_width_hz = sw.col('CHAN_WIDTH')[0][0] sw.close() self.name = 'Band_{0:.2f}MHz'.format(self.freq / 1e6) self.log = logging.getLogger('factor:{}'.format(self.name)) self.log.debug('Band name is {}'.format(self.name)) self.chunks_dir = os.path.join(factor_working_dir, 'chunks', self.name) # Do some checks self.check_freqs() self.check_parmdb() # Get the field RA and Dec obs = pt.table(self.files[0] + '::FIELD', ack=False) self.ra = np.degrees(float(obs.col('REFERENCE_DIR')[0][0][0])) if self.ra < 0.: self.ra = 360.0 + (self.ra) self.dec = np.degrees(float(obs.col('REFERENCE_DIR')[0][0][1])) obs.close() # Get the station diameter ant = pt.table(self.files[0] + '::ANTENNA', ack=False) self.diam = float(ant.col('DISH_DIAMETER')[0]) ant.close() # Find mean elevation and FOV for MS_id in xrange(self.numMS): # Add (virtual) elevation column to MS try: pt.addDerivedMSCal(self.files[MS_id]) except RuntimeError: # RuntimeError indicates column already exists pass # Calculate mean elevation tab = pt.table(self.files[MS_id], ack=False) if MS_id == 0: global_el_values = tab.getcol('AZEL1', rowincr=10000)[:, 1] else: global_el_values = np.hstack( (global_el_values, tab.getcol('AZEL1', rowincr=10000)[:, 1])) tab.close() # Remove (virtual) elevation column from MS pt.removeDerivedMSCal(self.files[MS_id]) self.mean_el_rad = np.mean(global_el_values) sec_el = 1.0 / np.sin(self.mean_el_rad) self.fwhm_deg = 1.1 * ( (3.0e8 / self.freq) / self.diam) * 180. / np.pi * sec_el # Check for SUBTRACTED_DATA_ALL column in original datasets self.has_sub_data = True self.has_sub_data_new = False for MSid in xrange(self.numMS): tab = pt.table(self.files[MSid], ack=False) if not 'SUBTRACTED_DATA_ALL' in tab.colnames(): self.log.error('SUBTRACTED_DATA_ALL column not found in file ' '{}'.format(self.files[MSid])) self.has_sub_data = False tab.close() if not self.has_sub_data: self.log.info('Exiting...') sys.exit(1) # cut input files into chunks if needed chunksize = 2400. # in seconds -> 40min self.chunk_input_files(chunksize, dirindparmdb, local_dir=local_dir, test_run=test_run) # Calculate times and number of samples self.sumsamples = 0 self.minSamplesPerFile = 4294967295 # If LOFAR lasts that many seconds then I buy you a beer. self.starttime = np.finfo('d').max self.endtime = 0. for MSid in xrange(self.numMS): tab = pt.table(self.files[MSid], ack=False) self.starttime = min(self.starttime, np.min(tab.getcol('TIME'))) self.endtime = max(self.endtime, np.min(tab.getcol('TIME'))) for t2 in tab.iter(["ANTENNA1", "ANTENNA2"]): if (t2.getcell('ANTENNA1', 0)) < (t2.getcell('ANTENNA2', 0)): self.timepersample = t2.col('TIME')[1] - t2.col('TIME')[0] numsamples = t2.nrows() self.sumsamples += numsamples self.minSamplesPerFile = min(self.minSamplesPerFile, numsamples) break tab.close() self.log.debug("Using {0} files.".format(len(self.files))) if skymodel_dirindep != None: self.log.debug("Using Skymodel: {}".format( os.path.basename(skymodel_dirindep)))