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)
예제 #3
0
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)
예제 #4
0
파일: band.py 프로젝트: rvweeren/factor
    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)))
예제 #5
0
파일: band.py 프로젝트: rvweeren/factor
    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)))