Exemple #1
0
 def _calc_PB(self, antenna):
     """
     Calculate the primary beam size of antenna, using dish diamenter
     and rest frequency
     Average antenna diamter and reference frequency are adopted for
     calculation.
     The input argument should be a list of antenna IDs.
     """
     casalog.post("Calculating Pirimary beam size:")
     # CAS-5410 Use private tools inside task scripts
     my_qa = qatool()
     
     pb_factor = 1.175
     # Reference frequency
     ref_freq = self.restfreq
     if type(ref_freq) in [float, numpy.float64]:
         ref_freq = my_qa.tos(my_qa.quantity(ref_freq, 'Hz'))
     if not my_qa.compare(ref_freq, 'Hz'):
         msg = "Could not get the reference frequency. " + \
               "Your data does not seem to have valid one in selected field.\n" + \
               "PB is not calculated.\n" + \
               "Please set restreq or cell manually to generate an image."
         raise Exception, msg
     # Antenna diameter
     antdiam_ave = self._get_average_antenna_diameter(antenna)
     # Calculate PB
     wave_length = 0.2997924 / my_qa.convert(my_qa.quantity(ref_freq),'GHz')['value']
     D_m = my_qa.convert(antdiam_ave, 'm')['value']
     lambda_D = wave_length / D_m * 3600. * 180 / numpy.pi
     PB = my_qa.quantity(pb_factor*lambda_D, 'arcsec')
     # Summary
     casalog.post("- Antenna diameter: %s m" % D_m)
     casalog.post("- Reference Frequency: %s" % ref_freq)
     casalog.post("PB size = %5.3f * lambda/D = %s" % (pb_factor, my_qa.tos(PB)))
     return PB
Exemple #2
0
    def execute(self):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        scan = self.worker.scan
        if self.kernel == 'regrid':
            if not qa.isquantity(self.chanwidth):
                errstr = "Invalid quantity chanwidth " + self.chanwidth
                raise Exception, errstr
            qchw = qa.quantity(self.chanwidth)
            oldUnit = scan.get_unit()
            if qchw['unit'] in ("", "channel", "pixel"):
                scan.set_unit("channel")
            elif qa.compare(self.chanwidth,"1Hz") or \
                     qa.compare(self.chanwidth,"1m/s"):
                scan.set_unit(qchw['unit'])
            else:
                errstr = "Invalid dimension of quantity chanwidth " + self.chanwidth
                raise Exception, errstr
            casalog.post("Regridding spectra in width " + self.chanwidth)
            scan.regrid_channel(width=qchw['value'],
                                plot=self.verify,
                                insitu=True)
            scan.set_unit(oldUnit)
        else:
            casalog.post("Smoothing spectra with kernel " + self.kernel)
            scan.smooth(kernel=self.kernel,
                        width=self.kwidth,
                        plot=self.verify,
                        insitu=True)
Exemple #3
0
 def __to_arcsec(self, angle):
     """convert angle to arcsec and return the value without unit."""
     my_qa = qatool()
     if my_qa.isangle(angle):
         return my_qa.getvalue(my_qa.convert(angle, "arcsec"))[0]
     elif my_qa.getunit(angle)=='': return float(angle)
     else: raise ValueError, "Invalid angle: %s" % (str(angle))
Exemple #4
0
def ssobjangdiam(srcName, epoch, ephemdata="",unit=""):
    """
    srcName: solar system object name (case insensitive)
    epoch: in string format (e.g. "2015/09/01:12:00:00")
    ephemdata: ephemeris data (default = "", look up the standard ~/alma/JPL_Horizons in the data repo
    unit: unit for the output ang. diam.
    """
  
    defaultDataPath = os.getenv("CASAPATH").split()[0] + "/data/ephemerides/JPL-Horizons/"
    me = taskinit.metool()
    qa = taskinit.qatool()
    if ephemdata!="":
       datapath = ephemdata
    else:
       mjd = me.epoch("utc",epoch)['m0']['value'] 
       datapath = findEphemTable(defaultDataPath, srcName, mjd)

    me.framecomet(datapath)
    me.doframe(me.epoch("utc", epoch))
    me.doframe(me.observatory("ALMA"))
   
    angdiamrad= me.cometangdiam()
    if unit=="" or unit=="rad":
        angdiam = angdiamrad
    else:
        angdiam = qa.convert(qa.quantity(angdiamrad), unit)

    return angdiam
Exemple #5
0
    def execute(self):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        scan = self.worker.scan
        if self.kernel == 'regrid':
            if not qa.isquantity(self.chanwidth):
                errstr = "Invalid quantity chanwidth "+self.chanwidth
                raise Exception, errstr
            qchw = qa.quantity(self.chanwidth)
            oldUnit = scan.get_unit()
            if qchw['unit'] in ("", "channel", "pixel"):
                scan.set_unit("channel")
            elif qa.compare(self.chanwidth,"1Hz") or \
                     qa.compare(self.chanwidth,"1m/s"):
                scan.set_unit(qchw['unit'])
            else:
                errstr = "Invalid dimension of quantity chanwidth "+self.chanwidth
                raise Exception, errstr
            casalog.post( "Regridding spectra in width "+self.chanwidth )
            scan.regrid_channel(width=qchw['value'],plot=self.verify,insitu=True)
            scan.set_unit(oldUnit)
        else:
            casalog.post( "Smoothing spectra with kernel "+self.kernel )
            scan.smooth(kernel=self.kernel,width=self.kwidth,plot=self.verify,insitu=True)
Exemple #6
0
    def _get_pointing_extent(self):
        ### MS selection is ignored. This is not quite right.
        casalog.post("Calculating map extent from pointings.")
        # CAS-5410 Use private tools inside task scripts
        my_qa = qatool()
        ret_dict = {}

        colname = self.pointingcolumn.upper()

        # MSs should be registered to imager
        if not self.is_imager_opened:
            raise RuntimeError('Internal error: imager should be opened here.')

        if self.phasecenter == "":
            # defaut is J2000
            base_mref = 'J2000'
        elif isinstance(self.phasecenter, int) or self.phasecenter.isdigit():
            # may be field id
            self.open_table(self.field_table)
            base_mref = self.table.getcolkeyword('PHASE_DIR',
                                                 'MEASINFO')['Ref']
            self.close_table()
        else:
            # may be phasecenter is explicitly specified
            pattern = '^([\-\+]?[0-9.]+([eE]?-?[0-9])?)|([\-\+]?[0-9][:h][0-9][:m][0-9.]s?)|([\-\+]?[0-9][.d][0-9][.d][0-9.]s?)$'
            items = self.phasecenter.split()
            base_mref = 'J2000'
            for i in items:
                s = i.strip()
                if re.match(pattern, s) is None:
                    base_mref = s
                    break

        mapextent = self.imager.mapextent(ref=base_mref,
                                          movingsource=self.ephemsrcname,
                                          pointingcolumntouse=colname)
        if mapextent['status'] is True:
            qheight = my_qa.quantity(mapextent['extent'][1], 'rad')
            qwidth = my_qa.quantity(mapextent['extent'][0], 'rad')
            qcent0 = my_qa.quantity(mapextent['center'][0], 'rad')
            qcent1 = my_qa.quantity(mapextent['center'][1], 'rad')
            scenter = '%s %s %s' % (base_mref, my_qa.formxxx(
                qcent0, 'hms'), my_qa.formxxx(qcent1, 'dms'))

            casalog.post("- Pointing center: %s" % scenter)
            casalog.post("- Pointing extent: [%s, %s] (projected)" % (my_qa.tos(qwidth), \
                                                                  my_qa.tos(qheight)))
            ret_dict['center'] = scenter
            ret_dict['width'] = qwidth
            ret_dict['height'] = qheight
        else:
            casalog.post(
                'Failed to derive map extent from the MSs registered to the imager probably due to mising valid data.',
                priority='SEVERE')
            ret_dict['center'] = ''
            ret_dict['width'] = my_qa.quantity(0.0, 'rad')
            ret_dict['height'] = my_qa.quantity(0.0, 'rad')
        return ret_dict
Exemple #7
0
 def __to_arcsec(self, angle):
     """convert angle to arcsec and return the value without unit."""
     my_qa = qatool()
     if my_qa.isangle(angle):
         return my_qa.getvalue(my_qa.convert(angle, "arcsec"))[0]
     elif my_qa.getunit(angle) == '':
         return float(angle)
     else:
         raise ValueError, "Invalid angle: %s" % (str(angle))
Exemple #8
0
def check_unit(unit_in,valid_unit=None,default_unit=None):
    # CAS-5410 Use private tools inside task scripts
    qa = qatool()

    if qa.check(unit_in):
        return valid_unit
    else:
        casalog.post('Undefined unit: \'%s\'...ignored'%(unit_in), priority='WARN')
        return default_unit
Exemple #9
0
def check_unit(unit_in, valid_unit=None, default_unit=None):
    # CAS-5410 Use private tools inside task scripts
    qa = qatool()

    if qa.check(unit_in):
        return valid_unit
    else:
        casalog.post('Undefined unit: \'%s\'...ignored' % (unit_in),
                     priority='WARN')
        return default_unit
Exemple #10
0
    def _get_pointing_extent(self):
        ### MS selection is ignored. This is not quite right.
        casalog.post("Calculating map extent from pointings.")
        # CAS-5410 Use private tools inside task scripts
        my_qa = qatool()
        ret_dict = {}
        
        colname = self.pointingcolumn.upper()

        # MSs should be registered to imager
        if not self.is_imager_opened:
            raise RuntimeError('Internal error: imager should be opened here.')
        
        if self.phasecenter == "":
            # defaut is J2000
            base_mref = 'J2000'
        elif isinstance(self.phasecenter, int) or self.phasecenter.isdigit():
            # may be field id
            self.open_table(self.field_table)
            base_mref = self.table.getcolkeyword('PHASE_DIR', 'MEASINFO')['Ref']
            self.close_table()
        else:
            # may be phasecenter is explicitly specified
            pattern = '^([\-\+]?[0-9.]+([eE]?-?[0-9])?)|([\-\+]?[0-9][:h][0-9][:m][0-9.]s?)|([\-\+]?[0-9][.d][0-9][.d][0-9.]s?)$'
            items = self.phasecenter.split()
            base_mref = 'J2000'
            for i in items:
                s = i.strip()
                if re.match(pattern, s) is None:
                    base_mref = s
                    break

        mapextent = self.imager.mapextent(ref=base_mref, movingsource=self.ephemsrcname, 
                                          pointingcolumntouse=colname)
        if mapextent['status'] is True:
            qheight = my_qa.quantity(mapextent['extent'][1], 'rad')
            qwidth = my_qa.quantity(mapextent['extent'][0], 'rad')
            qcent0 = my_qa.quantity(mapextent['center'][0], 'rad')
            qcent1 = my_qa.quantity(mapextent['center'][1], 'rad')
            scenter = '%s %s %s'%(base_mref, my_qa.formxxx(qcent0, 'hms'), 
                                  my_qa.formxxx(qcent1, 'dms'))

            casalog.post("- Pointing center: %s" % scenter)
            casalog.post("- Pointing extent: [%s, %s] (projected)" % (my_qa.tos(qwidth), \
                                                                  my_qa.tos(qheight)))
            ret_dict['center'] = scenter
            ret_dict['width'] = qwidth
            ret_dict['height'] = qheight
        else:
            casalog.post('Failed to derive map extent from the MSs registered to the imager probably due to mising valid data.', priority='SEVERE')
            ret_dict['center'] = ''
            ret_dict['width'] = my_qa.quantity(0.0, 'rad')
            ret_dict['height'] = my_qa.quantity(0.0, 'rad')
        return ret_dict
Exemple #11
0
 def __parse_width(self, val, cell_size_arcsec):
     """
     Convert value in unit of arcsec
     if val is angle, returns a float value in unit of arcsec.
     else the unit is assumed to be pixel and multiplied by cell_size_arcsec
     """
     my_qa = qatool()
     if my_qa.isangle(val): return self.__to_arcsec(val)
     elif my_qa.getunit(val) in ('', 'pixel'):
         return my_qa.getvalue(val)*cell_size_arcsec
     else: raise ValueError, "Invalid width %s" % str(val)
Exemple #12
0
    def __get_grid_parameters(self, calc=False):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        (nx,ny) = self.__get_mapsize()
        mapcenter = sdutil.get_map_center(self.center)
        (cellx,celly) = sdutil.get_cellx_celly(self.cell)
        if calc and \
               ((mapcenter.split() != 3) or not qa.compare(cellx, "rad")):
            #(mapcenter,cellx,celly) = self.__calc_center_and_cell(mapcenter, cellx, celly)
            (mapcenter,cellx,celly) = self.__get_center_and_cell(nx, ny, mapcenter, cellx, celly)
        return (nx,ny,cellx,celly,mapcenter)
Exemple #13
0
 def set_antenna(self, diam, blockage="0.0m", taper=10):
     """
     set parameters to construct antenna beam
     antenna diameter and blockage
     taper: the illumination taper in dB
     """
     # try quantity
     my_qa = qatool()
     self.antenna_diam_m = my_qa.getvalue(my_qa.convert(diam, "m"))[0]
     self.antenna_block_m = my_qa.getvalue(my_qa.convert(blockage, "m"))[0]
     self.taper = taper
     self.is_antenna_set = True
Exemple #14
0
 def set_antenna(self, diam, blockage="0.0m", taper=10):
     """
     set parameters to construct antenna beam
     antenna diameter and blockage
     taper: the illumination taper in dB
     """
     # try quantity
     my_qa = qatool()
     self.antenna_diam_m  = my_qa.getvalue(my_qa.convert(diam, "m"))[0]
     self.antenna_block_m = my_qa.getvalue(my_qa.convert(blockage, "m"))[0]
     self.taper = taper
     self.is_antenna_set = True
Exemple #15
0
 def __parse_width(self, val, cell_size_arcsec):
     """
     Convert value in unit of arcsec
     if val is angle, returns a float value in unit of arcsec.
     else the unit is assumed to be pixel and multiplied by cell_size_arcsec
     """
     my_qa = qatool()
     if my_qa.isangle(val): return self.__to_arcsec(val)
     elif my_qa.getunit(val) in ('', 'pixel'):
         return my_qa.getvalue(val) * cell_size_arcsec
     else:
         raise ValueError, "Invalid width %s" % str(val)
Exemple #16
0
 def _get_imsize(self, width, height, dx, dy):
     casalog.post("Calculating pixel size.")
     # CAS-5410 Use private tools inside task scripts
     my_qa = qatool()
     ny = numpy.ceil( ( my_qa.convert(height, my_qa.getunit(dy))['value'] /  \
                        my_qa.getvalue(dy) ) )
     nx = numpy.ceil( ( my_qa.convert(width, my_qa.getunit(dx))['value'] /  \
                        my_qa.getvalue(dx) ) )
     casalog.post("- Map extent: [%s, %s]" % (my_qa.tos(width), my_qa.tos(height)))
     casalog.post("- Cell size: [%s, %s]" % (my_qa.tos(dx), my_qa.tos(dy)))
     casalog.post("Image pixel numbers to cover the extent: [%d, %d] (projected)" % \
                  (nx+1, ny+1))
     return (int(nx+1), int(ny+1))
Exemple #17
0
    def __get_grid_parameters(self, calc=False):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        (nx, ny) = self.__get_mapsize()
        mapcenter = sdutil.get_map_center(self.center)
        (cellx, celly) = sdutil.get_cellx_celly(self.cell)
        if calc and \
               ((mapcenter.split() != 3) or not qa.compare(cellx, "rad")):
            #(mapcenter,cellx,celly) = self.__calc_center_and_cell(mapcenter, cellx, celly)
            (mapcenter, cellx,
             celly) = self.__get_center_and_cell(nx, ny, mapcenter, cellx,
                                                 celly)
        return (nx, ny, cellx, celly, mapcenter)
Exemple #18
0
 def __format_quantum_unit(self, data, unit):
     """
     Returns False if data has an unit which in not a variation of
     input unit.
     Otherwise, returns input data as a quantum string. The input
     unit is added to the return value if no unit is in data.
     """
     my_qa = qatool()
     if data == '' or my_qa.compare(data, unit):
         return data
     if my_qa.getunit(data) == '':
         casalog.post("No unit specified. Using '%s'" % unit)
         return '%f%s' % (data, unit)
     return None
Exemple #19
0
 def _get_imsize(self, width, height, dx, dy):
     casalog.post("Calculating pixel size.")
     # CAS-5410 Use private tools inside task scripts
     my_qa = qatool()
     ny = numpy.ceil( ( my_qa.convert(height, my_qa.getunit(dy))['value'] /  \
                        my_qa.getvalue(dy) ) )
     nx = numpy.ceil( ( my_qa.convert(width, my_qa.getunit(dx))['value'] /  \
                        my_qa.getvalue(dx) ) )
     casalog.post("- Map extent: [%s, %s]" %
                  (my_qa.tos(width), my_qa.tos(height)))
     casalog.post("- Cell size: [%s, %s]" % (my_qa.tos(dx), my_qa.tos(dy)))
     casalog.post("Image pixel numbers to cover the extent: [%d, %d] (projected)" % \
                  (nx+1, ny+1))
     return (int(nx + 1), int(ny + 1))
Exemple #20
0
 def __format_quantum_unit(self, data, unit):
     """
     Returns False if data has an unit which in not a variation of
     input unit.
     Otherwise, returns input data as a quantum string. The input
     unit is added to the return value if no unit is in data.
     """
     my_qa = qatool()
     if data == '' or my_qa.compare(data, unit):
         return data
     if my_qa.getunit(data) == '':
         casalog.post("No unit specified. Using '%s'" % unit)
         return '%f%s' % (data, unit)
     return None
Exemple #21
0
    def __set_unit_labels(self):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        self.abclbl = self.scan.get_unit()
        if self.fluxunit != '': ordlbl = self.fluxunit
        else: ordlbl = self.scan.get_fluxunit()
        self.intlbl = ordlbl+' * '+self.abclbl

        # Check units
        if self.abclbl == 'channel' and not qa.check(self.abclbl):
            qa.define('channel','1 _')

        self.xunit = check_unit(self.abclbl,self.abclbl,'_')
        self.intunit = check_unit(ordlbl,ordlbl+'.'+self.abclbl,'_.'+self.abclbl)
Exemple #22
0
    def _get_average_antenna_diameter(self, antenna):
        my_qa = qatool()
        self.open_table(self.antenna_table)
        try:
            antdiam_unit = self.table.getcolkeyword('DISH_DIAMETER', 'QuantumUnits')[0]
            diams = self.table.getcol('DISH_DIAMETER')
        finally:
            self.close_table()

        if len(antenna) == 0:
            antdiam_ave = my_qa.quantity(diams.mean(), antdiam_unit)
        else:
            d_ave = sum([diams[idx] for idx in antenna])/float(len(antenna))
            antdiam_ave = my_qa.quantity(d_ave, antdiam_unit)
        return antdiam_ave
Exemple #23
0
    def __set_unit_labels(self):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        self.abclbl = self.scan.get_unit()
        if self.fluxunit != '': ordlbl = self.fluxunit
        else: ordlbl = self.scan.get_fluxunit()
        self.intlbl = ordlbl + ' * ' + self.abclbl

        # Check units
        if self.abclbl == 'channel' and not qa.check(self.abclbl):
            qa.define('channel', '1 _')

        self.xunit = check_unit(self.abclbl, self.abclbl, '_')
        self.intunit = check_unit(ordlbl, ordlbl + '.' + self.abclbl,
                                  '_.' + self.abclbl)
Exemple #24
0
    def _get_average_antenna_diameter(self, antenna):
        my_qa = qatool()
        self.open_table(self.antenna_table)
        try:
            antdiam_unit = self.table.getcolkeyword('DISH_DIAMETER',
                                                    'QuantumUnits')[0]
            diams = self.table.getcol('DISH_DIAMETER')
        finally:
            self.close_table()

        if len(antenna) == 0:
            antdiam_ave = my_qa.quantity(diams.mean(), antdiam_unit)
        else:
            d_ave = sum([diams[idx] for idx in antenna]) / float(len(antenna))
            antdiam_ave = my_qa.quantity(d_ave, antdiam_unit)
        return antdiam_ave
Exemple #25
0
def primaryBeamArcsec(frequency,
                      diameter,
                      obscuration,
                      taper,
                      showEquation=True,
                      use2007formula=True,
                      fwhmfactor=None):
    """
    Implements the Baars formula: b*lambda / D.
      if use2007formula==False, use the formula from ALMA Memo 456        
      if use2007formula==True, use the formula from Baars 2007 book
        (see au.baarsTaperFactor)     
      In either case, the taper value is expected to be entered as positive.
        Note: if a negative value is entered, it is converted to positive.
    The effect of the central obstruction on the pattern is also accounted for
    by using a spline fit to Table 10.1 of Schroeder's Astronomical Optics.
    fwhmfactor: if given, then ignore the taper
    For further help and examples, see https://safe.nrao.edu/wiki/bin/view/ALMA/PrimaryBeamArcsec
    -- Todd Hunter
    Simplified version of the one in AnalysisUtils (revision 1.2204, 2015/02/18)
    """
    if (fwhmfactor != None):
        taper = effectiveTaper(fwhmfactor, diameter, obscuration,
                               use2007formula)
        if (taper == None): return
    if (taper < 0):
        taper = abs(taper)
    if (obscuration > 0.4 * diameter):
        print "This central obscuration is too large for the method of calculation employed here."
        return
    if (type(frequency) == str):
        my_qa = qatool()
        frequency = my_qa.getvalue(my_qa.convert(frequency, "Hz"))[0]
    lambdaMeters = 2.99792458e8 / frequency
    b = baarsTaperFactor(taper, use2007formula) * centralObstructionFactor(
        diameter, obscuration)
    if (showEquation):
        if (use2007formula):
            formula = "Baars (2007) Eq 4.13"
        else:
            formula = "ALMA memo 456 Eq. 18"
        casalog.post(
            "Coefficient from %s for a -%.1fdB edge taper and obscuration ratio=%g/%g = %.3f*lambda/D"
            % (formula, taper, obscuration, diameter, b))
    return (b * lambdaMeters * 3600 * 180 / (diameter * np.pi))
Exemple #26
0
    def __calc_center_and_cell(self, center, cellx, celly):
        from numpy import array
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        # Get map extent (in radian)
        dirarr = array(self.scan.get_directionval()).transpose()
        xmin = dirarr[0].min()
        xmax = dirarr[0].max()
        ymin = dirarr[1].min()
        ymax = dirarr[1].max()
        del dirarr
        # center of directions
        dircent = [0.5 * (xmax + xmin), 0.5 * (ymax + ymin)]
        centx = None
        centy = None
        # center is not specified
        if center.split() != 3:
            # set map center (string) to center of directions
            center = sdutil.get_map_center(dircent, unit="rad")
            # direction center in unit of radian
            (centx, centy) = dircent
        # cell is not specified
        if not qa.compare(cellx, "rad"):
            if not centx:
                # center is given. Get the value in radian
                lcent = center.split()
                centx = qa.convert(qa.toangle(lcent[1]), "rad")
                centy = qa.convert(qa.toangle(lcent[2]), "rad")
                # make sure centx is in +-pi of pointing center
                rotnum = round(abs(centx - dircent[0]) / (2 * pi))
                if centx < dircent[0]: rotnum *= -1
                centx -= rotnum * 2 * pi
            wx = 2. * max(abs(xmax - centx), abs(xmin - centx))
            wy = 2. * max(abs(ymax - centy), abs(ymin - centy))
            #print "mapsize = [%frad, %frad]" % (wx, wy)
            from numpy import cos
            (nx, ny) = self.__get_mapsize()
            cellx = qa.quantity(wx / float(max(nx - 1, 1)) * cos(centy), "rad")
            celly = qa.quantity(wy / float(max(ny - 1, 1)), "rad")
        return (center, qa.tos(cellx), qa.tos(celly))
Exemple #27
0
    def __calc_center_and_cell(self, center, cellx, celly):
        from numpy import array
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()

        # Get map extent (in radian)
        dirarr = array(self.scan.get_directionval()).transpose()
        xmin = dirarr[0].min()
        xmax = dirarr[0].max()
        ymin = dirarr[1].min()
        ymax = dirarr[1].max()
        del dirarr
        # center of directions
        dircent = [0.5*(xmax + xmin), 0.5*(ymax + ymin)]
        centx = None
        centy = None
        # center is not specified
        if center.split() != 3:
            # set map center (string) to center of directions
            center = sdutil.get_map_center(dircent, unit= "rad")
            # direction center in unit of radian
            (centx, centy) = dircent
        # cell is not specified
        if not qa.compare(cellx, "rad"):
            if not centx:
                # center is given. Get the value in radian
                lcent = center.split()
                centx = qa.convert(qa.toangle(lcent[1]), "rad")
                centy = qa.convert(qa.toangle(lcent[2]), "rad")
                # make sure centx is in +-pi of pointing center
                rotnum = round(abs(centx - dircent[0])/(2*pi))
                if centx < dircent[0]: rotnum *= -1
                centx -= rotnum*2*pi
            wx = 2. * max(abs(xmax-centx), abs(xmin-centx))
            wy = 2. * max(abs(ymax-centy), abs(ymin-centy))
            #print "mapsize = [%frad, %frad]" % (wx, wy)
            from numpy import cos
            (nx,ny) = self.__get_mapsize()
            cellx = qa.quantity(wx/float(max(nx-1,1))*cos(centy), "rad")
            celly = qa.quantity(wy/float(max(ny-1,1)), "rad")
        return (center, qa.tos(cellx), qa.tos(celly))
Exemple #28
0
def _calc_PB(vis, antenna_id, restfreq):
    """
    Calculate the primary beam size of antenna, using dish diamenter
    and rest frequency
    Average antenna diamter and reference frequency are adopted for
    calculation.
    The input argument should be a list of antenna IDs.
    """
    casalog.post("Calculating Pirimary beam size:")
    # CAS-5410 Use private tools inside task scripts
    my_qa = qatool()

    pb_factor = 1.175
    # Reference frequency
    ref_freq = restfreq
    if type(ref_freq) in [float, numpy.float64]:
        ref_freq = my_qa.tos(my_qa.quantity(ref_freq, 'Hz'))
    if not my_qa.compare(ref_freq, 'Hz'):
        msg = "Could not get the reference frequency. " + \
              "Your data does not seem to have valid one in selected field.\n" + \
              "PB is not calculated.\n" + \
              "Please set restreq or cell manually to generate an image."
        raise Exception, msg
    # Antenna diameter
    with open_table(os.path.join(vis, 'ANTENNA')) as tb:
        antdiam_ave = tb.getcell('DISH_DIAMETER', antenna_id)
    #antdiam_ave = self._get_average_antenna_diameter(antenna)
    # Calculate PB
    wave_length = 0.2997924 / my_qa.convert(my_qa.quantity(ref_freq),
                                            'GHz')['value']
    D_m = my_qa.convert(antdiam_ave, 'm')['value']
    lambda_D = wave_length / D_m * 3600. * 180 / numpy.pi
    PB = my_qa.quantity(pb_factor * lambda_D, 'arcsec')
    # Summary
    casalog.post("- Antenna diameter: %s m" % D_m)
    casalog.post("- Reference Frequency: %s" % ref_freq)
    casalog.post("PB size = %5.3f * lambda/D = %s" %
                 (pb_factor, my_qa.tos(PB)))
    return PB
Exemple #29
0
def primaryBeamArcsec(frequency, diameter, obscuration, taper, 
                      showEquation=True, use2007formula=True, fwhmfactor=None):
    """
    Implements the Baars formula: b*lambda / D.
      if use2007formula==False, use the formula from ALMA Memo 456        
      if use2007formula==True, use the formula from Baars 2007 book
        (see au.baarsTaperFactor)     
      In either case, the taper value is expected to be entered as positive.
        Note: if a negative value is entered, it is converted to positive.
    The effect of the central obstruction on the pattern is also accounted for
    by using a spline fit to Table 10.1 of Schroeder's Astronomical Optics.
    fwhmfactor: if given, then ignore the taper
    For further help and examples, see https://safe.nrao.edu/wiki/bin/view/ALMA/PrimaryBeamArcsec
    -- Todd Hunter
    Simplified version of the one in AnalysisUtils (revision 1.2204, 2015/02/18)
    """
    if (fwhmfactor != None):
        taper = effectiveTaper(fwhmfactor,diameter,obscuration,use2007formula)
        if (taper == None): return
    if (taper < 0):
        taper = abs(taper)
    if (obscuration>0.4*diameter):
        print "This central obscuration is too large for the method of calculation employed here."
        return
    if (type(frequency) == str):
        my_qa = qatool()
        frequency = my_qa.getvalue(my_qa.convert(frequency, "Hz"))[0]
    lambdaMeters = 2.99792458e8/frequency
    b = baarsTaperFactor(taper,use2007formula) * centralObstructionFactor(diameter, obscuration)
    if (showEquation):
        if (use2007formula):
            formula = "Baars (2007) Eq 4.13"
        else:
            formula = "ALMA memo 456 Eq. 18"
        casalog.post("Coefficient from %s for a -%.1fdB edge taper and obscuration ratio=%g/%g = %.3f*lambda/D" % (formula, taper, obscuration, diameter, b))
    return(b*lambdaMeters*3600*180/(diameter*np.pi))
Exemple #30
0
    def __execute_press(self):
        ###
        # Pressed-out method (Sofue & Reich 1979)
        ###
        casalog.post( 'Apply Pressed-out method' )

        # CAS-5410 Use private tools inside task scripts
        ia = gentools(['ia'])[0]

        # mask
        self.image = ia.newimagefromimage(infile=self.infiles,outfile=self.tmpmskname)
        # back-up original mask name
        is_initial_mask = (self.image.maskhandler('default')[0] != '')
        temp_maskname = "temporal"
        imshape = self.image.shape()
        ndim = len(imshape)
        nx = imshape[0]
        ny = imshape[1]
        if len(self.thresh) == 0:
            casalog.post( 'Use whole region' )
        else:
            # mask pixels beyond thresholds
            maskstr = ("mask('%s')" % self.tmpmskname)
            if self.thresh[0] != self.nolimit:
                maskstr += (" && '%s'>=%f" % (self.tmpmskname, self.thresh[0]))
            if self.thresh[1] != self.nolimit:
                maskstr += (" && '%s'<=%f" % (self.tmpmskname, self.thresh[1]))
            # Need to flush to image once to calcmask ... sigh
            self.image.done()
            self.image = ia.newimage( self.tmpmskname )
            self.image.calcmask(mask=maskstr, name=temp_maskname, asdefault=True)

        # smoothing
        #bmajor = 0.0
        #bminor = 0.0
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()
        if type(self.beamsize) == str:
            qbeamsize = qa.quantity(self.beamsize)
        else:
            qbeamsize = qa.quantity(self.beamsize,'arcsec')
        if type(self.smoothsize) == str:
            #bmajor = smoothsize
            #bminor = smoothsize
            qsmoothsize = qa.quantity(self.smoothsize)
        else:
            #bmajor = '%sarcsec' % (beamsize*smoothsize)
            #bminor = '%sarcsec' % (beamsize*smoothsize)
            qsmoothsize = qa.mul(qbeamsize,self.smoothsize)
        bmajor = qsmoothsize
        bminor = qsmoothsize
        pa = qa.quantity(0.0, 'deg')
        # masked channels are replaced by zero and convolved here.
        self.convimage = self.image.convolve2d( outfile=self.tmppolyname, major=bmajor, minor=bminor, pa=pa, 
                                                overwrite=True )
        self.convimage.done()

        # get dTij (original - smoothed)
        self.convimage = ia.imagecalc(outfile=self.tmpconvname, 
                                      pixels='"{org}" - "{conv}"'.format(org=self.tmpmskname,
                                                                         conv=self.tmppolyname),
                                      overwrite=True)

        # polynomial fit
        fitaxis = 0
        if self.direction == 0.0:
            fitaxis = 0
        elif self.direction == 90.0:
            fitaxis = 1
        else:
            raise Exception, "Sorry, the task don't support inclined scan with respect to horizontal or vertical axis, right now."
        # Replace duplicated method ia.fitpolynomial with
        # ia.fitprofile 
        #polyimage = convimage.fitpolynomial( fitfile=tmppolyname, axis=fitaxis, order=numpoly, overwrite=True )
        #polyimage.done()
        if os.path.exists( self.tmppolyname ):
            # CAS-5410 Use private tools inside task scripts
            cu = utilstool()
            cu.removetable([self.tmppolyname])
        self.convimage.setbrightnessunit('K')
        # Unfortunately, ia.fitprofile is very fragile.
        # Using numpy instead for fitting with masked pixels (KS, 2014/07/02)
        #resultdic = self.convimage.fitprofile( model=self.tmppolyname, axis=fitaxis, poly=self.numpoly, ngauss=0, multifit=True, gmncomps=0 )
        self.__polynomial_fit_model(image=self.tmpmskname, model=self.tmppolyname,axis=fitaxis, order=self.numpoly)
        polyimage = ia.newimage( self.tmppolyname )
        # set back defalut mask (need to get from self.image)
        avail_mask = polyimage.maskhandler('get')
        if is_initial_mask:
            casalog.post("copying mask from %s"%(self.infiles))
            polyimage.calcmask("mask('%s')"%self.infiles,asdefault=True)
        else: #no mask in the original image
            polyimage.calcmask('T', asdefault=True)
        if temp_maskname in avail_mask:
            polyimage.maskhandler('delete', name=temp_maskname)

        # subtract fitted image from original map
        subtracted = ia.imagecalc(outfile=self.outfile, 
                                  pixels='"{org}" - "{fit}"'.format(org=self.infiles,
                                                                    fit=self.tmppolyname),
                                  overwrite=self.overwrite)
        subtracted.done()

        # finalization
        polyimage.done(remove=True)
        self.convimage.done(remove=True)
        self.image.done()
Exemple #31
0
    def _summarize(self, fitsname, casaname, header, shape, taskargs):
        """Convenience function to populate dictionary for
           items to add to the ADMIT Summary. The contract
           function is self.summary(), called by AT()

        """

        self._summary = {}
        self._summary['fitsname'] = SummaryEntry(fitsname)
        self._summary['casaname'] = SummaryEntry(casaname)

        # these are one-to-one match keywords
        easy = [
            'object',
            'equinox',
            'observer',
            'date-obs',
            'datamax',
            'datamin',
            'badpixel',
            'vlsr',
        ]

        naxis = len(shape)
        self._summary['naxis'] = SummaryEntry(naxis)
        for i in range(naxis):
            j = i + 1
            jay = str(j)
            easy.append('crpix' + jay)
            easy.append('ctype' + jay)
            easy.append('crval' + jay)
            easy.append('cdelt' + jay)
            easy.append('cunit' + jay)
            self._summary['naxis' + jay] = SummaryEntry(int(shape[i]))

        # FITS is only 8 chars.
        if 'telescope' in header:
            self._summary['telescop'] = SummaryEntry(header['telescope'])

        if 'imtype' in header:
            self._summary['bunit'] = SummaryEntry(header['bunit'])

        for k in easy:
            if k in header:
                self._summary[k] = SummaryEntry(header[k])

        if 'restfreq' in header:
            self._summary['restfreq'] = SummaryEntry(header['restfreq'][0])

        # These are in imhead returned as dictionaries {'unit','value'}
        # so we have to munge them

        # convert beam parameters
        qa = taskinit.qatool()
        if 'beampa' in header:
            self._summary['bpa'] = SummaryEntry(
                qa.convert(header['beampa'], 'deg')['value'])
        if 'beammajor' in header:
            self._summary['bmaj'] = SummaryEntry(
                qa.convert(header['beammajor'], 'rad')['value'])
        if 'beamminor' in header:
            self._summary['bmin'] = SummaryEntry(
                qa.convert(header['beamminor'], 'rad')['value'])

        # Now tag all summary items with task name and task ID.

        for k in self._summary:
            self._summary[k].setTaskname("Ingest_AT")
            self._summary[k].setTaskID(self.id(True))
            self._summary[k].setTaskArgs(taskargs)
Exemple #32
0
    def run(self):
        """ The run method creates the BDP

            Parameters
            ----------
            None

            Returns
            -------
            None
        """
        self._summary = {}
        dt = utils.Dtime("Smooth")
        dt.tag("start")
        # get the input keys
        bmaj = self.getkey("bmaj")
        bmin = self.getkey("bmin")
        bpa = self.getkey("bpa")
        velres = self.getkey("velres")

        # take care of potential issues in the unit strings
        # @todo  if not provided?
        bmaj['unit'] = bmaj['unit'].lower()
        bmin['unit'] = bmin['unit'].lower()
        velres['unit'] = velres['unit'].lower()
        taskargs = "bmaj=%s bmin=%s bpa=%s velres=%s" % (bmaj, bmin, bpa,
                                                         velres)

        ia = taskinit.iatool()
        qa = taskinit.qatool()

        bdpnames = []
        for ibdp in self._bdp_in:
            istem = ibdp.getimagefile(bt.CASA)
            image_in = ibdp.baseDir() + istem

            bdp_name = self.mkext(istem, 'sim')
            image_out = self.dir(bdp_name)

            ia.open(image_in)
            h = casa.imhead(image_in, mode='list')
            pix_scale = np.abs(h['cdelt1'] *
                               206265.0)  # pix scale in asec @todo QA ?
            CC = 299792458.0  # speed of light  @todo somewhere else   [utils.c , but in km/s]

            rest_freq = h['crval3']
            # frequency pixel scale in km/s
            vel_scale = np.abs(CC * h['cdelt3'] / rest_freq / 1000.0)

            # unit conversion to arcsec (spatial) or km/s
            # (velocity) or some flavor of Hz.

            if (bmaj['unit'] == 'pixel'):
                bmaj = bmaj['value'] * pix_scale
            else:
                bmaj = bmaj['value']
            if (bmin['unit'] == 'pixel'):
                bmin = bmin['value'] * pix_scale
            else:
                bmin = bmin['value']

            hertz_input = False
            if velres['unit'] == 'pixel':
                velres['value'] = velres['value'] * vel_scale
                velres['unit'] = 'km/s'
            elif velres['unit'] == 'm/s':
                velres['value'] = velres['value'] / 1000.0
                velres['unit'] = 'km/s'
            elif velres['unit'][-2:] == 'hz':
                hertz_input = True
            elif velres['unit'] == 'km/s':
                pass
            else:
                logging.error("Unknown units in velres=%s" % velres['unit'])

            rdata = bmaj

            # we smooth in velocity first. if smoothing in velocity
            # the cube apparently must be closed afterwards and
            # then reopened if spatial smoothing is to be done.

            if velres['value'] > 0:
                # handle the different units allowed. CASA doesn't
                # like lowercase for hz units...
                if not hertz_input:
                    freq_res = str(
                        velres['value'] * 1000.0 / CC * rest_freq) + 'Hz'
                else:
                    freq_res = str(velres['value'])
                    # try to convert velres to km/s for debug purposes
                    velres['value'] = velres['value'] / rest_freq * CC / 1000.0
                    if (velres['unit'] == 'khz'):
                        velres['value'] = velres['value'] * 1000.0
                        velres['unit'] = 'kHz'
                    elif (velres['unit'] == 'mhz'):
                        velres['value'] = velres['value'] * 1E6
                        velres['unit'] = 'MHz'
                    elif (velres['unit'] == 'ghz'):
                        velres['value'] = velres['value'] * 1E9
                        velres['unit'] = 'GHz'
                    freq_res = freq_res + velres['unit']

                # NB: there is apparently a bug in CASA. only smoothing along the frequency
                # axis does not work. sepconvolve gives a unit error (says axis unit is radian rather
                # than Hz). MUST smooth in 2+ dimensions if you want this to work.

                if (velres['value'] < vel_scale):
                    raise Exception, "Desired velocity resolution %g less than pixel scale %g" % (
                        velres['value'], vel_scale)
                image_tmp = self.dir('tmp.smooth')
                im2=ia.sepconvolve(outfile=image_tmp,axes=[0,1,2], types=["boxcar","boxcar","gauss"],\
                                              widths=['1pix','1pix',freq_res], overwrite=True)
                im2.done()
                logging.debug("sepconvolve to %s" % image_out)
                # for some reason, doing this in memory does not seem to work, so outfile must be specified.

                logging.info(
                    "Smoothing cube to a velocity resolution of %s km/s" %
                    str(velres['value']))
                logging.info("Smoothing cube to a frequency resolution of %s" %
                             freq_res)
                ia.close()
                ia.open(image_tmp)
                dt.tag("sepconvolve")
            else:
                image_tmp = image_out

            # now do the spatial smoothing

            convolve_to_min_beam = True  # default is to convolve to a min enclosing beam

            if bmaj > 0 and bmin > 0:
                # form qa objects out of these so that casa can understand
                bmaj = qa.quantity(bmaj, 'arcsec')
                bmin = qa.quantity(bmin, 'arcsec')
                bpa = qa.quantity(bpa, 'deg')

                target_res = {}
                target_res['major'] = bmaj
                target_res['minor'] = bmin
                target_res['positionangle'] = bpa

                # throw an exception if cannot be convolved

                try:
                    # for whatever reason, if you give convolve2d a beam parameter,
                    # it complains ...
                    im2=ia.convolve2d(outfile=image_out,major = bmaj,\
                                             minor = bmin, pa = bpa,\
                                             targetres=True,overwrite=True)
                    im2.done()
                    logging.info(
                        "Smoothing cube to a resolution of %s by %s at a PA of %s"
                        % (str(bmaj['value']), str(
                            bmin['value']), str(bpa['value'])))
                    convolve_to_min_beam = False
                    achieved_res = target_res
                except:
                    # @todo   remind what you need ?
                    logging.error("Warning: Could not convolve to requested resolution of "\
                            +str(bmaj['value']) + " by " + str(bmin['value']) + \
                            " at a PA of "+ str(bpa['value']))
                    raise Exception, "Could not convolve to beam given!"
            dt.tag("convolve2d-1")

            if convolve_to_min_beam:
                restoring_beams = ia.restoringbeam()
                commonbeam = ia.commonbeam()
                # for whatever reason, setrestoringbeam does not use the same set of hashes...
                commonbeam['positionangle'] = commonbeam['pa']
                del commonbeam['pa']

                # if there's one beam, apparently the beams keyword does not exist
                if 'beams' in restoring_beams:
                    print "Smoothing cube to a resolution of "+  \
                         str(commonbeam['major']['value']) +" by "+ \
                         str(commonbeam['minor']['value'])+" at a PA of "\
                        +str(commonbeam['pa']['value'])
                    target_res = commonbeam
                    im2=ia.convolve2d(outfile=image_out,major=commonbeam['major'],\
                                               minor=commonbeam['minor'],\
                                               pa=commonbeam['positionangle'],\
                                               targetres=True,overwrite=True)
                    im2.done()
                    achieved_res = commonbeam
                    dt.tag("convolve2d-2")
                else:
                    print "One beam for all planes. Smoothing to common beam redundant."
                    achieved_res = commonbeam
                    if velres['value'] < 0:
                        ia.fromimage(outfile=image_out, infile=image_in)
                    # not really doing anything
                # else, we've already done what we needed to

                ia.setrestoringbeam(beam=achieved_res)
                rdata = achieved_res['major']['value']

            # else do no smoothing and just close the image

            ia.close()
            dt.tag("close")

            b1 = SpwCube_BDP(bdp_name)
            self.addoutput(b1)
            # need to update for multiple images.

            b1.setkey("image", Image(images={bt.CASA: bdp_name}))

            bdpnames = bdpnames.append(bdp_name)

            # and clean up the temp image before the next image
            if velres['value'] > 0:
                utils.remove(image_tmp)

        # thes are task arguments not summary entries.
        _bmaj = qa.convert(achieved_res['major'], 'rad')['value']
        _bmin = qa.convert(achieved_res['minor'], 'rad')['value']
        _bpa = qa.convert(achieved_res['positionangle'], 'deg')['value']
        vres = "%.2f %s" % (velres['value'], velres['unit'])

        logging.regression("SMOOTH: %f %f" % (rdata, velres['value']))

        self._summary["smooth"] = SummaryEntry(
            [bdp_name, convolve_to_min_beam, _bmaj, _bmin, _bpa, vres],
            "Smooth_AT", self.id(True), taskargs)
        dt.tag("done")
        dt.end()
Exemple #33
0
def fixsyscaltimes(vis,newinterval=2.0):
    """
    Fix TIME,INTERVAL columns in MS SYSCAL subtable
    Input:
     vis          the MS containing the offending SYSCAL subtable
     newinterval  the interval to use in revised entries

     This function is intended to repair MS SYSCAL tables that suffer from
     multiple TIME values (over antennas) per Tsys measurement.  The gencal
     task (mode='tsys' expects all antennas to share the same TIME value
     for each Tsys measurement (and this is usually true).  The function
     finds those measurements that have multiple TIMEs and replaces them
     with a common TIME value which takes the value
     mean(oldTIME-INTERVAL/2)+newinterval/2.
     Usually (always?), oldTIME-INTERVAL/2 is constant over antennas
     and represents the physical timestamp of the Tsys measurment.
     If the function finds no pathological timestamps, it does not
     revise the table.
    """

    import pylab as mypl
    import math as mymath
    myqa=taskinit.qatool()
    mytb=taskinit.tbtool()
    mytb.open(vis+'/SYSCAL',nomodify=False)

    spws=mypl.unique(mytb.getcol("SPECTRAL_WINDOW_ID"))

    for ispw in spws:
        st=mytb.query('SPECTRAL_WINDOW_ID=='+str(ispw),name='byspw')
        times=st.getcol('TIME')
        interval=st.getcol('INTERVAL')
        timestamps=times-interval/2
        t0=86400.0*mymath.floor(timestamps[0]/86400.0)

        utimes=mypl.unique(times-t0)
        nT=len(utimes)
        utimestamps=mypl.unique(mypl.floor(timestamps)-t0)
        nTS=len(utimestamps)
        
        msg='In spw='+str(ispw)+' found '+str(nTS)+' Tsys measurements with '+str(nT)+' TIMEs...'
        if nT==nTS:
            msg+='OK.'
            print msg

        else:
            msg+=' which is too many, so fixing it:'
            print msg 

            for uts in utimestamps:
                mask = ((mypl.floor(timestamps))-t0==uts)
                uTIMEs=mypl.unique(times[mask])
                nTIMEs=len(uTIMEs)
                newtime = mypl.mean(times[mask]-interval[mask]/2) + newinterval/2
                msg='  Found '+str(nTIMEs)+' TIMEs at timestamp='+str(myqa.time(str(newtime-newinterval/2)+'s',form='ymd')[0])
                if nTIMEs>1:
                    msg+=':'
                    print msg
                    print '   TIMEs='+str([myqa.time(str(t)+'s',form='ymd')[0] for t in uTIMEs])+' --> '+str(myqa.time(str(newtime)+'s',form='ymd')[0])+' w/ INTERVAL='+str(newinterval)
                    times[mask]=newtime
                    interval[mask]=newinterval
                    st.putcol('TIME',times)
                    st.putcol('INTERVAL',interval)
                else:
                    msg+='...ok.'
                    print msg
        st.close()
    mytb.close()
Exemple #34
0
def fixsyscaltimes(vis,newinterval=2.0):
    """
    Fix TIME,INTERVAL columns in MS SYSCAL subtable
    Input:
     vis          the MS containing the offending SYSCAL subtable
     newinterval  the interval to use in revised entries

     This function is intended to repair MS SYSCAL tables that suffer from
     multiple TIME values (over antennas) per Tsys measurement.  The gencal
     task (mode='tsys' expects all antennas to share the same TIME value
     for each Tsys measurement (and this is usually true).  The function
     finds those measurements that have multiple TIMEs and replaces them
     with a common TIME value which takes the value
     mean(oldTIME-INTERVAL/2)+newinterval/2.
     Usually (always?), oldTIME-INTERVAL/2 is constant over antennas
     and represents the physical timestamp of the Tsys measurment.
     If the function finds no pathological timestamps, it does not
     revise the table.
    """

    import pylab as mypl
    import math as mymath
    myqa=taskinit.qatool()
    mytb=taskinit.tbtool()
    mytb.open(vis+'/SYSCAL',nomodify=False)

    spws=mypl.unique(mytb.getcol("SPECTRAL_WINDOW_ID"))

    for ispw in spws:
        st=mytb.query('SPECTRAL_WINDOW_ID=='+str(ispw),name='byspw')
        times=st.getcol('TIME')
        interval=st.getcol('INTERVAL')
        timestamps=times-interval/2
        t0=86400.0*mymath.floor(timestamps[0]/86400.0)

        utimes=mypl.unique(times-t0)
        nT=len(utimes)
        utimestamps=mypl.unique(mypl.floor(timestamps)-t0)
        nTS=len(utimestamps)
        
        msg='In spw='+str(ispw)+' found '+str(nTS)+' Tsys measurements with '+str(nT)+' TIMEs...'
        if nT==nTS:
            msg+='OK.'
            print msg

        else:
            msg+=' which is too many, so fixing it:'
            print msg 

            for uts in utimestamps:
                mask = ((mypl.floor(timestamps))-t0==uts)
                uTIMEs=mypl.unique(times[mask])
                nTIMEs=len(uTIMEs)
                newtime = mypl.mean(times[mask]-interval[mask]/2) + newinterval/2
                msg='  Found '+str(nTIMEs)+' TIMEs at timestamp='+str(myqa.time(str(newtime-newinterval/2)+'s',form='ymd')[0])
                if nTIMEs>1:
                    msg+=':'
                    print msg
                    print '   TIMEs='+str([myqa.time(str(t)+'s',form='ymd')[0] for t in uTIMEs])+' --> '+str(myqa.time(str(newtime)+'s',form='ymd')[0])+' w/ INTERVAL='+str(newinterval)
                    times[mask]=newtime
                    interval[mask]=newinterval
                    st.putcol('TIME',times)
                    st.putcol('INTERVAL',interval)
                else:
                    msg+='...ok.'
                    print msg
        st.close()
    mytb.close()
Exemple #35
0
    def calc_statistics(self):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()
        self.savestats = ''
        self.returnstats = {}
        rootidx = []

        #         # Warning for multi-IF data
        #         if len(self.scan.getifnos()) > 1:
        #             casalog.post( 'The scantable contains multiple IF data.', priority='WARN' )
        #             casalog.post( 'Note the same mask(s) are applied to all IFs based on CHANNELS.', priority='WARN' )
        #             casalog.post( 'Baseline ranges may be incorrect for all but IF=%d.\n' % (self.scan.getif(0)), priority='WARN' )

        # backup spec unit
        unit_org = self.scan.get_unit()
        self.scan.set_unit('channel')

        basesel = self.scan.get_selection()
        maskdict = {-1: []}
        if self.spw.strip() not in ['', '*']:
            maskdict = self.scan.parse_spw_selection(self.spw)
        for ifno, masklist in maskdict.items():
            self.masklist = masklist
            if ifno > -1:
                sel = sd.selector(basesel)
                sel.set_ifs([ifno])
                self.scan.set_selection(sel)
                rootidx += list(self.scan._get_root_row_idx())
                del sel
                msg = "Working on IF%s" % (ifno)
                if (self.interactive): print "===%s===" % (msg)
                del msg

            # set mask
            self.__set_mask()

            # set formatter
            self.__set_formatter()

            # set unit labels
            self.__set_unit_labels()

            # calculate statistics
            #statsdict = get_stats(s, msk, formstr)
            self.__calc_stats()
            self.__merge_stats()

            # reset selection
            if ifno > -1: self.scan.set_selection(basesel)

        # restore spec unit
        self.scan.set_unit(unit_org)
        # sort return values in order of root table row idx
        if len(rootidx) > 0:
            self.__sort_stats_order(rootidx)
        # return values instead of lists if nrow = 1.
        if len(self.returnstats[self.returnstats.keys()[0]]) == 1:
            self.__stats_list_to_val()
        # reshape statsdict for return
        for k in ['min', 'max']:
            retsts = {}
            retsts['value'] = self.returnstats.pop('%s_abc' % (k))
            retsts['unit'] = self.xunit
            self.returnstats['%s_abscissa' % (k)] = retsts
        for (k, u) in [('eqw', self.xunit), ('totint', self.intunit)]:
            retsts = {}
            retsts['value'] = self.returnstats[k]
            retsts['unit'] = u
            self.returnstats[k] = retsts
Exemple #36
0
def _get_restfreq_if_empty(vislist, spw, field, restfreq):
    qa = qatool()
    rf = None
    # if restfreq is nonzero float value, return it
    if isinstance(restfreq, float):
        if restfreq != 0.0:
            rf = restfreq
    # if restfreq is valid frequency string, return it
    # numeric string is interpreted as a value in the unit of Hz
    elif isinstance(restfreq, str):
        q = qa.convert(qa.quantity(restfreq), 'Hz')
        if q['unit'] == 'Hz' and q['value'] > 0.0:
            rf = restfreq
    # if restfreq is valid quantity, return it
    elif isinstance(restfreq, dict):
        q = qa.convert(restfreq, 'Hz')
        if q['unit'] == 'Hz' and q['value'] > 0.0:
            rf = restfreq

    if isinstance(vislist, str):
        vis = vislist
    elif hasattr(vislist, '__iter__'):
        vis = vislist[0]
    else:
        raise RuntimeError(
            'Internal Error: invalid vislist \'{0}\''.format(vislist))

    if isinstance(spw, str):
        spwsel = spw
    elif hasattr(spw, '__iter__'):
        spwsel = spw[0]
    else:
        raise RuntimeError(
            'Internal Error: invalid spw selection \'{0}\''.format(spw))

    if isinstance(field, str):
        fieldsel = field
    elif hasattr(field, '__iter__'):
        fieldsel = field[0]
    else:
        raise RuntimeError(
            'Internal Error: invalid field selection \'{0}\''.format(field))

    with open_ms(vis) as ms:
        ms.msselect({'spw': spwsel, 'field': fieldsel})
        ndx = ms.msselectedindices()
        if len(ndx['spw']) > 0:
            spwid = ndx['spw'][0]
        else:
            spwid = None
        if len(ndx['field']) > 0:
            fieldid = ndx['field'][0]
        else:
            fieldid = None
    sourceid = None
    if fieldid is not None:
        with open_table(os.path.join(vis, 'FIELD')) as tb:
            sourceid = tb.getcell('SOURCE_ID', fieldid)
        if sourceid < 0:
            sourceid = None
    if rf is None:
        # if restfrequency is defined in SOURCE table, return it
        with open_table(os.path.join(vis, 'SOURCE')) as tb:
            if 'REST_FREQUENCY' in tb.colnames():
                tsel = None
                taql = ''
                if spwid is not None:
                    taql = 'SPECTRAL_WINDOW_ID == {0}'.format(spwid)
                if sourceid is not None:
                    delimiter = '&&' if len(taql) > 0 else ''
                    taql += '{0}SOURCE_ID == {1}'.format(delimiter, sourceid)
                if len(taql) > 0:
                    tsel = tb.query(taql)
                    t = tsel
                else:
                    t = tb
                try:
                    nrow = t.nrows()
                    if nrow > 0:
                        for irow in xrange(nrow):
                            if t.iscelldefined('REST_FREQUENCY', irow):
                                rfs = t.getcell('REST_FREQUENCY', irow)
                                if len(rfs) > 0:
                                    rf = rfs[0]
                                    break
                finally:
                    if tsel is not None:
                        tsel.close()

    if rf is None:
        if spwid is None:
            spwid = 0
        # otherwise, return mean frequency of given spectral window
        with open_table(os.path.join(vis, 'SPECTRAL_WINDOW')) as tb:
            cf = tb.getcell('CHAN_FREQ', spwid)
            rf = cf.mean()

    assert rf is not None

    return rf
Exemple #37
0
    def calc_statistics(self):
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()
        self.savestats = ''
        self.returnstats = {}
        rootidx = []

#         # Warning for multi-IF data
#         if len(self.scan.getifnos()) > 1:
#             casalog.post( 'The scantable contains multiple IF data.', priority='WARN' )
#             casalog.post( 'Note the same mask(s) are applied to all IFs based on CHANNELS.', priority='WARN' )
#             casalog.post( 'Baseline ranges may be incorrect for all but IF=%d.\n' % (self.scan.getif(0)), priority='WARN' )

        # backup spec unit
        unit_org = self.scan.get_unit()
        self.scan.set_unit('channel')
        
        basesel = self.scan.get_selection()
        maskdict = {-1: []}
        if self.spw.strip() not in ['', '*']:
            maskdict = self.scan.parse_spw_selection(self.spw)
        for ifno, masklist in maskdict.items():
            self.masklist = masklist
            if ifno > -1:
                sel = sd.selector(basesel)
                sel.set_ifs([ifno])
                self.scan.set_selection(sel)
                rootidx += list(self.scan._get_root_row_idx())
                del sel
                msg = "Working on IF%s" % (ifno)
                if (self.interactive): print "===%s===" % (msg)
                del msg
            
            # set mask
            self.__set_mask()

            # set formatter
            self.__set_formatter()

            # set unit labels
            self.__set_unit_labels()

            # calculate statistics
            #statsdict = get_stats(s, msk, formstr)
            self.__calc_stats()
            self.__merge_stats()

            # reset selection
            if ifno > -1: self.scan.set_selection(basesel)

        # restore spec unit
        self.scan.set_unit(unit_org)
        # sort return values in order of root table row idx
        if len(rootidx) > 0:
            self.__sort_stats_order(rootidx)
        # return values instead of lists if nrow = 1.
        if len(self.returnstats[ self.returnstats.keys()[0] ]) == 1:
            self.__stats_list_to_val()
        # reshape statsdict for return
        for k in ['min','max']:
            retsts = {}
            retsts['value'] = self.returnstats.pop('%s_abc'%(k))
            retsts['unit'] = self.xunit
            self.returnstats['%s_abscissa'%(k)] = retsts
        for (k,u) in [('eqw',self.xunit),('totint',self.intunit)]:
            retsts = {}
            retsts['value'] = self.returnstats[k]
            retsts['unit'] = u
            self.returnstats[k] = retsts
Exemple #38
0
def set_beam_size(vis, imagename, field, spw, baseline, scan, intent,
                  ephemsrcname, pointingcolumntouse, antenna_name,
                  antenna_diameter, restfreq, gridfunction, convsupport,
                  truncate, gwidth, jwidth):
    """
    Set estimated beam size to the image.
    """
    is_alma = antenna_name[0:2] in ['PM', 'DV', 'DA', 'CM']
    blockage = '0.75m' if is_alma else '0.0m'

    with open_ia(imagename) as ia:
        csys = ia.coordsys()
        outref = csys.referencecode('direction')[0]
        cell = list(csys.increment(type='direction', format='s')['string'])

    old_tool = OldImagerBasedTools()
    sampling_params = old_tool.get_pointing_sampling_params(
        vis,
        field,
        spw,
        baseline,
        scan,
        intent,
        outref=outref,
        movingsource=ephemsrcname,
        pointingcolumntouse=pointingcolumntouse,
        antenna_name=antenna_name)
    qa = qatool()
    casalog.post('sampling_params={0}'.format(sampling_params))
    xsampling, ysampling = qa.getvalue(
        qa.convert(sampling_params['sampling'], 'arcsec'))
    angle = qa.getvalue(qa.convert(sampling_params['angle'], 'deg'))[0]

    casalog.post('Detected raster sampling = [{0:f}, {1:f}] arcsec'.format(
        xsampling, ysampling))

    # handling of failed sampling detection
    valid_sampling = True
    # TODO: copy from sdimaging implementation
    sampling = [xsampling, ysampling]
    if abs(xsampling) < 2.2e-3 or not numpy.isfinite(xsampling):
        casalog.post(
            "Invalid sampling=%s arcsec. Using the value of orthogonal direction=%s arcsec"
            % (xsampling, ysampling),
            priority="WARN")
        sampling = [ysampling]
        angle = 0.0
        valid_sampling = False
    if abs(ysampling) < 1.0e-3 or not numpy.isfinite(ysampling):
        if valid_sampling:
            casalog.post(
                "Invalid sampling=%s arcsec. Using the value of orthogonal direction=%s arcsec"
                % (ysampling, xsampling),
                priority="WARN")
            sampling = [xsampling]
            angle = 0.0
            valid_sampling = True
    # reduce sampling and cell if it's possible
    if len(sampling) > 1 and abs(sampling[0] -
                                 sampling[1]) <= 0.01 * abs(sampling[0]):
        sampling = [sampling[0]]
        angle = 0.0
        if cell[0] == cell[1]: cell = [cell[0]]
    if valid_sampling:
        # actual calculation of beam size
        bu = sdbeamutil.TheoreticalBeam()
        bu.set_antenna(antenna_diameter, blockage)
        bu.set_sampling(sampling, "%fdeg" % angle)
        bu.set_image_param(cell, restfreq, gridfunction, convsupport, truncate,
                           gwidth, jwidth, is_alma)
        bu.summary()
        imbeam_dict = bu.get_beamsize_image()
        casalog.post("Setting image beam: major=%s, minor=%s, pa=%s" % (
            imbeam_dict['major'],
            imbeam_dict['minor'],
            imbeam_dict['pa'],
        ))
        # set beam size to image
        with open_ia(imagename) as ia:
            ia.setrestoringbeam(**imbeam_dict)
    else:
        # BOTH sampling was invalid
        casalog.post(
            "Could not detect valid raster sampling. Exitting without setting beam size to image",
            priority='WARN')
Exemple #39
0
    def __execute_press(self):
        ###
        # Pressed-out method (Sofue & Reich 1979)
        ###
        casalog.post("Apply Pressed-out method")

        # CAS-5410 Use private tools inside task scripts
        ia = gentools(["ia"])[0]

        # mask
        self.image = ia.newimagefromimage(infile=self.infiles, outfile=self.tmpmskname)
        # back-up original mask name
        is_initial_mask = self.image.maskhandler("default")[0] != ""
        temp_maskname = "temporal"
        imshape = self.image.shape()
        nx = imshape[0]
        ny = imshape[1]
        nchan = imshape[2]
        if len(self.thresh) == 0:
            casalog.post("Use whole region")
        else:
            # mask pixels beyond thresholds
            maskstr = "mask('%s')" % self.tmpmskname
            if self.thresh[0] != self.nolimit:
                maskstr += " && '%s'>=%f" % (self.tmpmskname, self.thresh[0])
            if self.thresh[1] != self.nolimit:
                maskstr += " && '%s'<=%f" % (self.tmpmskname, self.thresh[1])
            # Need to flush to image once to calcmask ... sigh
            self.image.done()
            self.image = ia.newimage(self.tmpmskname)
            self.image.calcmask(mask=maskstr, name=temp_maskname, asdefault=True)

        # smoothing
        # bmajor = 0.0
        # bminor = 0.0
        # CAS-5410 Use private tools inside task scripts
        qa = qatool()
        if type(self.beamsize) == str:
            qbeamsize = qa.quantity(self.beamsize)
        else:
            qbeamsize = qa.quantity(self.beamsize, "arcsec")
        if type(self.smoothsize) == str:
            # bmajor = smoothsize
            # bminor = smoothsize
            qsmoothsize = qa.quantity(self.smoothsize)
        else:
            # bmajor = '%sarcsec' % (beamsize*smoothsize)
            # bminor = '%sarcsec' % (beamsize*smoothsize)
            qsmoothsize = qa.mul(qbeamsize, self.smoothsize)
        bmajor = qsmoothsize
        bminor = qsmoothsize
        # masked channels are replaced by zero and convolved here.
        self.convimage = self.image.convolve2d(outfile=self.tmpconvname, major=bmajor, minor=bminor, overwrite=True)
        self.convimage.done()
        self.convimage = ia.newimage(self.tmpconvname)

        # get dTij (original - smoothed)
        if len(imshape) == 4:
            # with polarization axis
            npol = imshape[3]
            for ichan in range(nchan):
                for ipol in range(npol):
                    pixmsk = self.image.getchunk([0, 0, ichan, ipol], [nx - 1, ny - 1, ichan, ipol])
                    pixsmo = self.convimage.getchunk([0, 0, ichan, ipol], [nx - 1, ny - 1, ichan, ipol])
                    pixsub = pixmsk - pixsmo
                    self.convimage.putchunk(pixsub, [0, 0, ichan, ipol])
        elif len(imshape) == 3:
            for ichan in range(nchan):
                # no polarization axis
                pixmsk = self.image.getchunk([0, 0, ichan], [nx - 1, ny - 1, ichan])
                pixsmo = self.convimage.getchunk([0, 0, ichan], [nx - 1, ny - 1, ichan])
                pixsub = pixmsk - pixsmo
                self.convimage.putchunk(pixsub, [0, 0, ichan])

        # polynomial fit
        fitaxis = 0
        if self.direction == 0.0:
            fitaxis = 0
        elif self.direction == 90.0:
            fitaxis = 1
        else:
            raise Exception, "Sorry, the task don't support inclined scan with respect to horizontal or vertical axis, right now."
        # Replace duplicated method ia.fitpolynomial with
        # ia.fitprofile
        # polyimage = convimage.fitpolynomial( fitfile=tmppolyname, axis=fitaxis, order=numpoly, overwrite=True )
        # polyimage.done()
        if os.path.exists(self.tmppolyname):
            # CAS-5410 Use private tools inside task scripts
            cu = utilstool()
            cu.removetable([self.tmppolyname])
        self.convimage.setbrightnessunit("K")
        # Unfortunately, ia.fitprofile is very fragile.
        # Using numpy instead for fitting with masked pixels (KS, 2014/07/02)
        # resultdic = self.convimage.fitprofile( model=self.tmppolyname, axis=fitaxis, poly=self.numpoly, ngauss=0, multifit=True, gmncomps=0 )
        self.__polynomial_fit_model(image=self.tmpmskname, model=self.tmppolyname, axis=fitaxis, order=self.numpoly)
        polyimage = ia.newimage(self.tmppolyname)
        # set back defalut mask (need to get from self.image)
        avail_mask = polyimage.maskhandler("get")
        if is_initial_mask:
            casalog.post("copying mask from %s" % (self.infiles))
            polyimage.calcmask("mask('%s')" % self.infiles, asdefault=True)
        else:  # no mask in the original image
            polyimage.calcmask("T", asdefault=True)
        if temp_maskname in avail_mask:
            polyimage.maskhandler("delete", name=temp_maskname)

        # subtract fitted image from original map
        imageorg = ia.newimage(self.infiles)
        if len(imshape) == 4:
            # with polarization axis
            npol = imshape[3]
            for ichan in range(nchan):
                for ipol in range(npol):
                    pixorg = imageorg.getchunk([0, 0, ichan, ipol], [nx - 1, ny - 1, ichan, ipol])
                    pixpol = polyimage.getchunk([0, 0, ichan, ipol], [nx - 1, ny - 1, ichan, ipol])
                    pixsub = pixorg - pixpol
                    polyimage.putchunk(pixsub, [0, 0, ichan, ipol])
        elif len(imshape) == 3:
            # no polarization axis
            for ichan in range(nchan):
                pixorg = imageorg.getchunk([0, 0, ichan], [nx - 1, ny - 1, ichan])
                pixpol = polyimage.getchunk([0, 0, ichan], [nx - 1, ny - 1, ichan])
                pixsub = pixorg - pixpol
                polyimage.putchunk(pixsub, [0, 0, ichan])

        # output
        polyimage.rename(self.outfile, overwrite=self.overwrite)

        polyimage.done()
        self.convimage.done(remove=True)
        self.image.done()
        imageorg.done()
Exemple #40
0
import astropy.units as u
from astropy import constants
try:
    from casac import casac
    synthesisutils = casac.synthesisutils
    from taskinit import msmdtool, casalog, qatool, tbtool, mstool, iatool
    from tasks import tclean
except ImportError:
    from casatools import (quanta as qatool, table as tbtool, msmetadata as
                           msmdtool, synthesisutils, ms as mstool, image as
                           iatool)
    from casatasks import casalog, tclean

msmd = msmdtool()
ms = mstool()
qa = qatool()
st = synthesisutils()
tb = tbtool()
ia = iatool()


def logprint(string, origin='almaimf_metadata', priority='INFO'):
    print(string)
    casalog.post(string, origin=origin, priority=priority)


def is_7m(ms):
    """
    Determine if a measurement set includes 7m data
    """
    msmd.open(ms)
Exemple #41
0
def _get_pointing_extent(phasecenter, vislist, field, spw, antenna, scan,
                         intent, pointingcolumntouse, ephemsrcname):
    ### MS selection is ignored. This is not quite right.
    casalog.post("Calculating map extent from pointings.")
    # CAS-5410 Use private tools inside task scripts
    my_qa = qatool()
    ret_dict = {}

    if isinstance(vislist, str):
        vis = vislist
    else:
        vis = vislist[0]

    colname = pointingcolumntouse.upper()

    if phasecenter == "":
        # defaut is J2000
        base_mref = 'J2000'
    elif isinstance(phasecenter, int) or phasecenter.isdigit():
        # may be field id
        with open_table(os.path.join(vis, 'FIELD')) as tb:
            base_mref = tb.getcolkeyword('PHASE_DIR', 'MEASINFO')['Ref']
    else:
        # may be phasecenter is explicitly specified
        pattern = '^([\-\+]?[0-9.]+([eE]?-?[0-9])?)|([\-\+]?[0-9][:h][0-9][:m][0-9.]s?)|([\-\+]?[0-9][.d][0-9][.d][0-9.]s?)$'
        items = phasecenter.split()
        base_mref = 'J2000'
        for i in items:
            s = i.strip()
            if re.match(pattern, s) is None:
                base_mref = s
                break

    t = OldImagerBasedTools()
    mapextent = t.get_map_extent(vislist,
                                 field,
                                 spw,
                                 antenna,
                                 scan,
                                 intent,
                                 ref=base_mref,
                                 movingsource=ephemsrcname,
                                 pointingcolumntouse=pointingcolumntouse)
    #mapextent = self.imager.mapextent(ref=base_mref, movingsource=ephemsrcname,
    #                                  pointingcolumntouse=colname)
    if mapextent['status'] is True:
        qheight = my_qa.quantity(mapextent['extent'][1], 'rad')
        qwidth = my_qa.quantity(mapextent['extent'][0], 'rad')
        qcent0 = my_qa.quantity(mapextent['center'][0], 'rad')
        qcent1 = my_qa.quantity(mapextent['center'][1], 'rad')
        scenter = '%s %s %s' % (base_mref, my_qa.formxxx(
            qcent0, 'hms'), my_qa.formxxx(qcent1, 'dms'))

        casalog.post("- Pointing center: %s" % scenter)
        casalog.post("- Pointing extent: [%s, %s] (projected)" % (my_qa.tos(qwidth), \
                                                              my_qa.tos(qheight)))
        ret_dict['center'] = scenter
        ret_dict['width'] = qwidth
        ret_dict['height'] = qheight
    else:
        casalog.post(
            'Failed to derive map extent from the MSs registered to the imager probably due to mising valid data.',
            priority='SEVERE')
        ret_dict['center'] = ''
        ret_dict['width'] = my_qa.quantity(0.0, 'rad')
        ret_dict['height'] = my_qa.quantity(0.0, 'rad')
    return ret_dict
Exemple #42
0
class sdimaging_worker(sdutil.sdtask_template_imaging):
    def __init__(self, **kwargs):
        super(sdimaging_worker, self).__init__(**kwargs)
        self.imager_param = {}
        self.sorted_idx = []

    def parameter_check(self):
        # outfile check
        sdutil.assert_outfile_canoverwrite_or_nonexistent(
            self.outfile, 'im', self.overwrite)
        sdutil.assert_outfile_canoverwrite_or_nonexistent(
            self.outfile + '.weight', 'im', self.overwrite)
        # fix spw
        if type(self.spw) == str:
            self.spw = self.__format_spw_string(self.spw)
        # check unit of start and width
        # fix default
        if self.mode == 'channel':
            if self.start == '': self.start = 0
            if self.width == '': self.width = 1
        else:
            if self.start == 0: self.start = ''
            if self.width == 1: self.width = ''
        # fix unit
        if self.mode == 'frequency':
            myunit = 'Hz'
        elif self.mode == 'velocity':
            myunit = 'km/s'
        else:  # channel
            myunit = ''

        for name in ['start', 'width']:
            param = getattr(self, name)
            new_param = self.__format_quantum_unit(param, myunit)
            if new_param == None:
                raise ValueError, "Invalid unit for %s in mode %s: %s" % \
                      (name, self.mode, param)
            setattr(self, name, new_param)

        casalog.post("mode='%s': start=%s, width=%s, nchan=%d" % \
                     (self.mode, self.start, self.width, self.nchan))

        # check length of selection parameters
        if is_string_type(self.infiles):
            nfile = 1
            self.infiles = [self.infiles]
        else:
            nfile = len(self.infiles)

        for name in ['field', 'spw', 'antenna', 'scanno']:
            param = getattr(self, name)
            if not self.__check_selection_length(param, nfile):
                raise ValueError, "Length of %s != infiles." % (name)
        # set convsupport default
        if self.convsupport >= 0 and self.gridfunction.upper() != 'SF':
            casalog.post("user defined convsupport is ignored for %s kernel" %
                         self.gridfunction,
                         priority='WARN')
            self.convsupport = -1

    def __format_spw_string(self, spw):
        """
        Returns formatted spw selection string which is accepted by imager.
        """
        if type(spw) != str:
            raise ValueError, "The parameter should be string."
        if spw.strip() == '*': spw = ''
        # WORKAROUND for CAS-6422, i.e., ":X~Y" fails while "*:X~Y" works.
        if spw.startswith(":"): spw = '*' + spw
        return spw

    def __format_quantum_unit(self, data, unit):
        """
        Returns False if data has an unit which in not a variation of
        input unit.
        Otherwise, returns input data as a quantum string. The input
        unit is added to the return value if no unit is in data.
        """
        my_qa = qatool()
        if data == '' or my_qa.compare(data, unit):
            return data
        if my_qa.getunit(data) == '':
            casalog.post("No unit specified. Using '%s'" % unit)
            return '%f%s' % (data, unit)
        return None

    def __check_selection_length(self, data, nfile):
        """
        Returns true if data is either a string, an array with length
        1 or nfile
        """
        if not is_string_type(data) and len(data) not in [1, nfile]:
            return False
        return True

    def get_selection_param_for_ms(self, fileid, param):
        """
        Returns valid selection string for a certain ms

        Arguments
            fileid : file idx in infiles list
            param : string (array) selection value
        """
        if is_string_type(param):
            return param
        elif len(param) == 1:
            return param[0]
        else:
            return param[fileid]

    def get_selection_idx_for_ms(self, file_idx):
        """
        Returns a dictionary of selection indices for i-th MS in infiles

        Argument: file idx in infiles list
        """
        if file_idx < len(self.infiles) and file_idx > -1:
            vis = self.infiles[file_idx]
            field = self.get_selection_param_for_ms(file_idx, self.field)
            spw = self.get_selection_param_for_ms(file_idx, self.spw)
            spw = self.__format_spw_string(spw)
            antenna = self.get_selection_param_for_ms(file_idx, self.antenna)
            if antenna == -1: antenna = ''
            scan = self.get_selection_param_for_ms(file_idx, self.scanno)
            intent = self.get_selection_param_for_ms(file_idx, self.intent)
            my_ms = gentools(['ms'])[0]
            sel_ids = my_ms.msseltoindex(vis=vis,
                                         spw=spw,
                                         field=field,
                                         baseline=antenna,
                                         scan=scan)
            fieldid = list(
                sel_ids['field']) if len(sel_ids['field']) > 0 else -1
            baseline = self.format_ac_baseline(sel_ids['antenna1'])
            scanid = list(sel_ids['scan']) if len(sel_ids['scan']) > 0 else ""
            # SPW (need to get a list of valid spws instead of -1)
            if len(sel_ids['channel']) > 0:
                spwid = [chanarr[0] for chanarr in sel_ids['channel']]
            elif spw == "":  # No spw selection
                my_ms.open(vis)
                try:
                    spwinfo = my_ms.getspectralwindowinfo()
                except:
                    raise
                finally:
                    my_ms.close()

                spwid = [int(idx) for idx in spwinfo.keys()]
            else:
                raise RuntimeError("Invalid spw selction, %s ,for MS %d" (
                    str(spw), file_idx))

            return {
                'field': fieldid,
                'spw': spwid,
                'baseline': baseline,
                'scan': scanid,
                'intent': intent,
                'antenna1': sel_ids['antenna1']
            }
        else:
            raise ValueError, ("Invalid file index, %d" % file_idx)

    def format_ac_baseline(self, in_antenna):
        """ format auto-correlation baseline string from antenna idx list """
        # exact match string
        if is_string_type(in_antenna):
            if (len(in_antenna) != 0) and (in_antenna.find('&') == -1) \
                   and (in_antenna.find(';')==-1):
                in_antenna = + '&&&'
            return in_antenna
        # single integer -> list of int
        if type(in_antenna) == int:
            if in_antenna >= 0:
                in_antenna = [in_antenna]
            else:
                return -1
        # format auto-corr string from antenna idices.
        baseline = ''
        for idx in in_antenna:
            if len(baseline) > 0: baseline += ';'
            if idx >= 0:
                baseline += (str(idx) + '&&&')
        return baseline

    def compile(self):
        # imaging mode
        self.imager_param['mode'] = self.mode

        # Work on selection of the first table in sorted list
        # to get default restfreq and outframe
        imhelper = cleanhelper(self.imager, self.infiles, casalog=casalog)
        imhelper.sortvislist(self.spw, self.mode, self.width)
        self.sorted_idx = imhelper.sortedvisindx
        selection_ids = self.get_selection_idx_for_ms(self.sorted_idx[0])
        self.__update_subtable_name(self.infiles[self.sorted_idx[0]])
        # field
        fieldid = selection_ids['field'][0] if type(
            selection_ids['field']) != int else selection_ids['field']
        sourceid = -1
        self.open_table(self.field_table)
        source_ids = self.table.getcol('SOURCE_ID')
        self.close_table()
        if self.field == '' or fieldid == -1:
            sourceid = source_ids[0]
        elif fieldid >= 0 and fieldid < len(source_ids):
            sourceid = source_ids[fieldid]
        else:
            raise ValueError, "No valid field in the first MS."

        # restfreq
        if self.restfreq == '' and self.source_table != '':
            self.open_table(self.source_table)
            source_ids = self.table.getcol('SOURCE_ID')
            for i in range(self.table.nrows()):
                if sourceid == source_ids[i] \
                       and self.table.iscelldefined('REST_FREQUENCY',i) \
                       and (selection_ids['spw'] == -1 or \
                            self.table.getcell('SPECTRAL_WINDOW_ID', i) in selection_ids['spw']):
                    rf = self.table.getcell('REST_FREQUENCY', i)
                    if len(rf) > 0:
                        self.restfreq = self.table.getcell(
                            'REST_FREQUENCY', i)[0]
                        break
            self.close_table()
            casalog.post("restfreq set to %s" % self.restfreq, "INFO")
        # REST_FREQUENCY column is optional (need retry if not exists)
        self.imager_param['restfreq'] = self.restfreq

        #
        # spw (define representative spw id = spwid_ref)
        spwid_ref = selection_ids['spw'][0] if type(
            selection_ids['spw']) != int else selection_ids['spw']
        # Invalid spw selection should have handled at msselectiontoindex().
        # -1 means all spw are selected.
        self.open_table(self.spw_table)
        if spwid_ref < 0:
            for id in range(self.table.nrows()):
                if self.table.getcell('NUM_CHAN', id) > 0:
                    spwid_ref = id
                    break
            if spwid_ref < 0:
                self.close_table()
                msg = 'No valid spw id exists in the first table'
                raise ValueError, msg
        self.allchannels = self.table.getcell('NUM_CHAN', spwid_ref)
        freq_chan0 = self.table.getcell('CHAN_FREQ', spwid_ref)[0]
        freq_inc0 = self.table.getcell('CHAN_WIDTH', spwid_ref)[0]
        # in case rest frequency is not defined yet.
        if self.restfreq == '':
            self.restfreq = '%fHz' % self.table.getcell(
                'CHAN_FREQ', spwid_ref).mean()
            self.imager_param['restfreq'] = self.restfreq
            casalog.post(
                "Using mean freq of spw %d as restfreq: %s" %
                (spwid_ref, self.restfreq), "INFO")
        self.close_table()
        self.imager_param['spw'] = -1  #spwid_ref

        # outframe (force using the current frame)
        self.imager_param['outframe'] = self.outframe
        if self.outframe == '':
            if len(self.infiles) > 1:
                # The default will be 'LSRK'
                casalog.post(
                    "Multiple MS inputs. The default outframe is set to 'LSRK'"
                )
                self.imager_param['outframe'] = 'LSRK'
            else:
                # get from MS
                my_ms = gentools(['ms'])[0]
                my_ms.open(self.infiles[0])
                spwinfo = my_ms.getspectralwindowinfo()
                my_ms.close()
                del my_ms
                for key, spwval in spwinfo.items():
                    if spwval['SpectralWindowId'] == spwid_ref:
                        self.imager_param['outframe'] = spwval['Frame']
                        casalog.post("Using frequency frame of MS, '%s'" %
                                     self.imager_param['outframe'])
                        break
            if self.imager_param['outframe'] == '':
                raise Exception, "Internal error of getting frequency frame of spw=%d." % spwid_ref
        else:
            casalog.post("Using frequency frame defined by user, '%s'" %
                         self.imager_param['outframe'])

#         # antenna
#         in_antenna = self.antenna # backup for future use
#         if type(self.antenna)==int:
#             if self.antenna >= 0:
#                 self.antenna=str(self.antenna)+'&&&'
#         else:
#             if (len(self.antenna) != 0) and (self.antenna.find('&') == -1) \
#                    and (self.antenna.find(';')==-1):
#                 self.antenna = self.antenna + '&&&'

    def _configure_map_property(self):
        selection_ids = self.get_selection_idx_for_ms(self.sorted_idx[0])

        # stokes
        if self.stokes == '':
            self.stokes = 'I'
        self.imager_param['stokes'] = self.stokes

        # gridfunction

        # outfile
        if os.path.exists(self.outfile) and self.overwrite:
            os.system('rm -rf %s' % (self.outfile))
        if os.path.exists(self.outfile + '.weight') and self.overwrite:
            os.system('rm -rf %s' % (self.outfile + '.weight'))

        # cell
        cell = self.cell
        if cell == '' or cell[0] == '':
            # Calc PB
            grid_factor = 3.
            casalog.post(
                "The cell size will be calculated using PB size of antennas in the first MS"
            )
            qPB = self._calc_PB(selection_ids['antenna1'])
            cell = '%f%s' % (qPB['value'] / grid_factor, qPB['unit'])
            casalog.post("Using cell size = PB/%4.2F = %s" %
                         (grid_factor, cell))

        (cellx, celly) = sdutil.get_cellx_celly(cell, unit='arcmin')
        self.imager_param['cellx'] = cellx
        self.imager_param['celly'] = celly

        # Calculate Pointing center and extent (if necessary)
        # return a dictionary with keys 'center', 'width', 'height'
        #imsize = self.imsize
        imsize = sdutil._to_list(self.imsize, int) or \
            sdutil._to_list(self.imsize, numpy.integer)
        if imsize is None:
            imsize = self.imsize if hasattr(self.imsize,
                                            '__iter__') else [self.imsize]
            imsize = [int(numpy.ceil(v)) for v in imsize]
            casalog.post(
                "imsize is not integers. force converting to integer pixel numbers.",
                priority="WARN")
            casalog.post("rounded-up imsize: %s --> %s" %
                         (str(self.imsize), str(imsize)))

        phasecenter = self.phasecenter
        if self.phasecenter == "" or \
               len(imsize) == 0 or imsize[0] < 1:
            map_param = self._get_pointing_extent()
            # imsize
            if len(imsize) == 0 or imsize[0] < 1:
                imsize = self._get_imsize(map_param['width'],
                                          map_param['height'], cellx, celly)
                if self.phasecenter != "":
                    casalog.post(
                        "You defined phasecenter but not imsize. The image will cover as wide area as pointing in MS extends, but be centered at phasecenter. This could result in a strange image if your phasecenter is a part from the center of pointings",
                        priority='WARN')
                if imsize[0] > 1024 or imsize[1] > 1024:
                    casalog.post(
                        "The calculated image pixel number is larger than 1024. It could take time to generate the image depending on your computer resource. Please wait...",
                        priority='WARN')

            # phasecenter
            # if empty, it should be determined here...
            if self.phasecenter == "":
                phasecenter = map_param['center']

        # imsize
        (nx, ny) = sdutil.get_nx_ny(imsize)
        self.imager_param['nx'] = nx
        self.imager_param['ny'] = ny

        # phasecenter
        self.imager_param['phasecenter'] = phasecenter

        self.imager_param['movingsource'] = self.ephemsrcname

        # channel map
        imhelper = cleanhelper(self.imager, self.infiles, casalog=casalog)
        imhelper.sortvislist(self.spw, self.mode, self.width)
        spwsel = str(',').join([str(spwid) for spwid in selection_ids['spw']])
        srestf = self.imager_param['restfreq'] if is_string_type(
            self.imager_param['restfreq']
        ) else "%fHz" % self.imager_param['restfreq']
        (imnchan, imstart, imwidth) = imhelper.setChannelizeDefault(
            self.mode, spwsel, self.field, self.nchan, self.start, self.width,
            self.imager_param['outframe'], self.veltype,
            self.imager_param['phasecenter'], srestf)
        del imhelper

        # start and width
        if self.mode == 'velocity':
            startval = [self.imager_param['outframe'], imstart]
            widthval = imwidth
        elif self.mode == 'frequency':
            startval = [self.imager_param['outframe'], imstart]
            widthval = imwidth
        else:  #self.mode==channel
            startval = int(self.start)
            widthval = int(self.width)

        if self.nchan < 0: self.nchan = self.allchannels
        self.imager_param['start'] = startval
        self.imager_param['step'] = widthval
        self.imager_param['nchan'] = imnchan  #self.nchan

    def execute(self):
        # imaging
        casalog.post("Start imaging...", "INFO")
        if len(self.infiles) == 1:
            self.open_imager(self.infiles[0])
            selection_ids = self.get_selection_idx_for_ms(0)
            spwsel = self.get_selection_param_for_ms(0, self.spw)
            if spwsel.strip() in ['', '*']: spwsel = selection_ids['spw']
            ### TODO: channel selection based on spw
            ok = self.imager.selectvis(
                field=selection_ids['field'],
                #spw=selection_ids['spw'],
                spw=spwsel,
                nchan=-1,
                start=0,
                step=1,
                baseline=selection_ids['baseline'],
                scan=selection_ids['scan'],
                intent=selection_ids['intent'])
            if not ok:
                raise ValueError, "Selection is empty: you may want to review this MS selection"
        else:
            self.close_imager()
            #self.sorted_idx.reverse()
            for idx in self.sorted_idx.__reversed__():
                name = self.infiles[idx]
                selection_ids = self.get_selection_idx_for_ms(idx)
                spwsel = self.get_selection_param_for_ms(idx, self.spw)
                if spwsel.strip() in ['', '*']: spwsel = selection_ids['spw']
                ### TODO: channel selection based on spw
                self.imager.selectvis(
                    vis=name,
                    field=selection_ids['field'],
                    #spw=selection_ids['spw'],
                    spw=spwsel,
                    nchan=-1,
                    start=0,
                    step=1,
                    baseline=selection_ids['baseline'],
                    scan=selection_ids['scan'],
                    intent=selection_ids['intent'])
                # need to do this
                self.is_imager_opened = True

        # it should be called after infiles are registered to imager
        self._configure_map_property()

        casalog.post(
            "Using phasecenter \"%s\"" % (self.imager_param['phasecenter']),
            "INFO")

        self.imager.defineimage(**self.imager_param)  #self.__get_param())
        self.imager.setoptions(ftmachine='sd', gridfunction=self.gridfunction)
        self.imager.setsdoptions(pointingcolumntouse=self.pointingcolumn,
                                 convsupport=self.convsupport,
                                 truncate=self.truncate,
                                 gwidth=self.gwidth,
                                 jwidth=self.jwidth,
                                 minweight=0.,
                                 clipminmax=self.clipminmax)
        self.imager.makeimage(type='singledish', image=self.outfile)
        weightfile = self.outfile + ".weight"
        self.imager.makeimage(type='coverage', image=weightfile)
        self.close_imager()

        if not os.path.exists(self.outfile):
            raise RuntimeError, "Failed to generate output image '%s'" % self.outfile
        if not os.path.exists(weightfile):
            raise RuntimeError, "Failed to generate weight image '%s'" % weightfile
        # Convert output images to proper output frame
        my_ia = gentools(['ia'])[0]
        my_ia.open(self.outfile)
        csys = my_ia.coordsys()
        csys.setconversiontype(spectral=csys.referencecode('spectra')[0])
        my_ia.setcoordsys(csys.torecord())

        my_ia.close()

        # Mask image pixels whose weight are smaller than minweight.
        # Weight image should have 0 weight for pixels below < minweight
        casalog.post("Start masking the map using minweight = %f" % \
                     self.minweight, "INFO")
        my_ia.open(weightfile)
        try:
            stat = my_ia.statistics(mask="'" + weightfile + "' > 0.0",
                                    robust=True)
            valid_pixels = stat['npts']
        except RuntimeError, e:
            if e.message.find('No valid data found.') >= 0:
                valid_pixels = [0]
            else:
                raise e
        if len(valid_pixels) == 0 or valid_pixels[0] == 0:
            my_ia.close()
            casalog.post(
                "All pixels weight zero. This indicates no data in MS is in image area. Mask will not be set. Please check your image parameters.",
                "WARN")
            return
        median_weight = stat['median'][0]
        weight_threshold = median_weight * self.minweight
        casalog.post("Median of weight in the map is %f" % median_weight, \
                     "INFO")
        casalog.post("Pixels in map with weight <= median(weight)*minweight = %f will be masked." % \
                     (weight_threshold),"INFO")
        ###Leaving the original logic to calculate the number of masked pixels via
        ###product of median of and min_weight (which i don't understand the logic)
        ### if one wanted to find how many pixel were masked one could easily count the
        ### number of pixels set to false
        ### e.g  after masking self.outfile below one could just do this
        ### nmasked_pixels=tb.calc('[select from "'+self.outfile+'"/mask0'+'"  giving [nfalse(PagedArray )]]')
        my_tb = gentools(['tb'])[0]
        nmask_pixels = 0
        nchan = stat['trc'][3] + 1
        casalog.filter('ERROR')  ### hide the useless message of tb.calc

        ### doing it by channel to make sure it does not go out of memory
        ####tab.calc try to load the whole chunk in ram
        for k in range(nchan):
            nmask_pixels += my_tb.calc('[select from "' + weightfile +
                                       '"  giving [ntrue(map[,,,' + str(k) +
                                       '] <=' +
                                       str(median_weight * self.minweight) +
                                       ')]]')['0'][0]
        casalog.filter()  ####set logging back to normal

        casalog.filter()  ####set logging back to normal
        imsize = numpy.product(my_ia.shape())
        my_ia.close()
        # Modify default mask
        my_ia.open(self.outfile)
        my_ia.calcmask("'%s'>%f" % (weightfile, weight_threshold),
                       asdefault=True)
        my_ia.close()
        masked_fraction = 100. * (
            1. - (imsize - nmask_pixels) / float(valid_pixels[0]))
        casalog.post("This amounts to %5.1f %% of the area with nonzero weight." % \
                    ( masked_fraction ),"INFO")
        casalog.post("The weight image '%s' is returned by this task, if the user wishes to assess the results in detail." \
                     % (weightfile), "INFO")

        # Calculate theoretical beam size
        casalog.post("Calculating image beam size.")
        if self.gridfunction.upper() not in ['SF']:
            casalog.post(
                "Beam size definition for '%s' kernel is experimental." %
                self.gridfunction,
                priority='WARN')
            casalog.post(
                "You may want to take careful look at the restoring beam in the image.",
                priority='WARN')
        my_msmd = gentools(['msmd'])[0]
        # antenna diameter and blockage
        ref_ms_idx = self.sorted_idx[0]
        ref_ms_name = self.infiles[ref_ms_idx]
        selection_ids = self.get_selection_idx_for_ms(ref_ms_idx)
        ant_idx = selection_ids['antenna1']
        diameter = self._get_average_antenna_diameter(ant_idx)
        my_msmd.open(ref_ms_name)
        ant_name = my_msmd.antennanames(ant_idx)
        my_msmd.close()
        is_alma = False
        for name in ant_name:
            if name[0:2] in ["PM", "DV", "DA", "CM"]:
                is_alma = True
                break
        blockage = "0.75m" if is_alma else "0.0m"  # unknown blockage diameter
        # output reference code
        my_ia.open(self.outfile)
        csys = my_ia.coordsys()
        my_ia.close()
        outref = csys.referencecode('direction')[0]
        cell = list(csys.increment(type='direction', format='s')['string'])
        # pointing sampling
        ref_ms_spw = self.get_selection_param_for_ms(ref_ms_idx, self.spw)
        ref_ms_field = self.get_selection_param_for_ms(ref_ms_idx, self.field)
        ref_ms_scan = self.get_selection_param_for_ms(ref_ms_idx, self.scanno)
        # xSampling, ySampling, angle = sdutil.get_ms_sampling_arcsec(ref_ms_name, spw=ref_ms_spw,
        #                                                             antenna=selection_ids['baseline'],
        #                                                             field=ref_ms_field,
        #                                                             scan=ref_ms_scan,#timerange='',
        #                                                             outref=outref)

        # obtain sampling interval for beam calculation.
        self.open_imager(ref_ms_name)
        ok = self.imager.selectvis(
            field=ref_ms_field,
            #spw=selection_ids['spw'],
            spw=ref_ms_spw,
            nchan=-1,
            start=0,
            step=1,
            baseline=selection_ids['baseline'],
            scan=ref_ms_scan,
            intent=selection_ids['intent'])
        if len(ant_idx) > 1:
            casalog.post(
                "Using only antenna %s to calculate sampling interval" %
                ant_name[0])
        ptg_samp = self.imager.pointingsampling(
            pattern='raster',
            ref=outref,
            movingsource=self.ephemsrcname,
            pointingcolumntouse=self.pointingcolumn,
            antenna=('%s&&&' % ant_name[0]))
        self.close_imager()
        my_qa = qatool()
        xSampling, ySampling = my_qa.getvalue(
            my_qa.convert(ptg_samp['sampling'], 'arcsec'))
        angle = my_qa.getvalue(my_qa.convert(ptg_samp['angle'], "deg"))[0]

        casalog.post("Detected raster sampling = [%f, %f] arcsec" %
                     (xSampling, ySampling))
        # handling of failed sampling detection
        valid_sampling = True
        sampling = [xSampling, ySampling]
        if abs(xSampling) < 2.2e-3 or not numpy.isfinite(xSampling):
            casalog.post(
                "Invalid sampling=%s arcsec. Using the value of orthogonal direction=%s arcsec"
                % (xSampling, ySampling),
                priority="WARN")
            sampling = [ySampling]
            angle = 0.0
            valid_sampling = False
        if abs(ySampling) < 1.0e-3 or not numpy.isfinite(ySampling):
            if valid_sampling:
                casalog.post(
                    "Invalid sampling=%s arcsec. Using the value of orthogonal direction=%s arcsec"
                    % (ySampling, xSampling),
                    priority="WARN")
                sampling = [xSampling]
                angle = 0.0
                valid_sampling = True
        # reduce sampling and cell if it's possible
        if len(sampling) > 1 and abs(sampling[0] -
                                     sampling[1]) <= 0.01 * abs(sampling[0]):
            sampling = [sampling[0]]
            angle = 0.0
            if cell[0] == cell[1]: cell = [cell[0]]
        if valid_sampling:
            # actual calculation of beam size
            bu = sdbeamutil.TheoreticalBeam()
            bu.set_antenna(diameter, blockage)
            bu.set_sampling(sampling, "%fdeg" % angle)
            bu.set_image_param(cell, self.restfreq, self.gridfunction,
                               self.convsupport, self.truncate, self.gwidth,
                               self.jwidth, is_alma)
            bu.summary()
            imbeam_dict = bu.get_beamsize_image()
            casalog.post("Setting image beam: major=%s, minor=%s, pa=%s" % (
                imbeam_dict['major'],
                imbeam_dict['minor'],
                imbeam_dict['pa'],
            ))
            # set beam size to image
            my_ia.open(self.outfile)
            my_ia.setrestoringbeam(**imbeam_dict)
            my_ia.close()
        else:
            #BOTH sampling was invalid
            casalog.post(
                "Could not detect valid raster sampling. Exitting without setting beam size to image",
                priority='WARN')
Exemple #43
0
            raise Exception, 'Unable to continue with MMS processing'

        pdh.setupCluster('split')

        # Execute the jobs
        try:
            pdh.go()
        except Exception, instance:
            casalog.post('%s' % instance, 'ERROR')
            return False

        return True

    # Create local copies of some tools
    mtlocal = mttool()
    qalocal = qatool()
    mslocal = mstool()

    try:

        # Gather all the parameters in a dictionary.
        config = {}

        if keepflags:
            taqlstr = ''
        else:
            taqlstr = "NOT (FLAG_ROW OR ALL(FLAG))"

        if type(correlation) == list:
            correlation = ', '.join(correlation)
            correlation = correlation.upper()
Exemple #44
0
def getPlotantsAntennaInfo(msname, log, exclude, checkbaselines):

	tb, me = gentools(['tb', 'me'])
	qa = qatool()

	telescope, arrayPos = getPlotantsObservatoryInfo(msname)
	arrayWgs84 = me.measure(arrayPos, 'WGS84')
	arrayLon, arrayLat, arrayAlt = [arrayWgs84[i]['value'] 
		for i in ['m0','m1','m2']]

	# Open the ANTENNA subtable to get the names of the antennas in this MS and
	# their positions.  Note that the entries in the ANTENNA subtable are pretty
	# much in random order, so antNames translates between their index and name
	# (e.g., index 11 = STD155).  We'll need these indices for later, since the
	# main data table refers to the antennas by their indices, not names.

	anttabname = msname + '/ANTENNA'
	tb.open(anttabname)
	# Get antenna names from antenna table
	antNames = np.array(tb.getcol("NAME")).tolist()
	stationNames = np.array(tb.getcol("STATION")).tolist()
	if telescope == 'VLBA':  # names = ant@station
		antNames = ['@'.join(antsta) for antsta in zip(antNames,stationNames)]
	# Get antenna positions from antenna table
	antPositions = np.array([me.position('ITRF', qa.quantity(x, 'm'),
		qa.quantity(y, 'm'), qa.quantity(z, 'm'))
		for (x, y, z) in tb.getcol('POSITION').transpose()])
	tb.close()

	allAntIds = range(len(antNames))
	if checkbaselines:
		# Get antenna ids from main table; this will add to runtime
		tb.open(msname)
		ants1 = tb.getcol('ANTENNA1')
		ants2 = tb.getcol('ANTENNA2')
		tb.close()
		antIdsUsed = list(set(np.append(ants1, ants2)))
	else:
		# use them all!
		antIdsUsed = allAntIds

	# handle exclude -- remove from antIdsUsed
	for antId in exclude:
		try:
			antNameId = antNames[antId] + " (id " + str(antId) + ")"
			antIdsUsed.remove(antId)
			casalog.post("Exclude antenna " + antNameId)
		except ValueError:
			casalog.post("Cannot exclude antenna " + antNameId + ": not in main table", "WARN")

	# apply antIdsUsed mask
	antNames = [antNames[i] for i in antIdsUsed]
	antPositions = [antPositions[i] for i in antIdsUsed]
	stationNames = [stationNames[i] for i in antIdsUsed]

	nAnts = len(antIdsUsed)
	print "Number of points being plotted:", nAnts
	casalog.post("Number of points being plotted: " + str(nAnts))
	if nAnts == 0: # excluded all antennas
		return telescope, antNames, [], [], []

	# Get the names, indices, and lat/lon/alt coords of "good" antennas.
	antWgs84s = np.array([me.measure(pos, 'WGS84') for pos in antPositions])

	# Convert from lat, lon, alt to X, Y, Z (unless VLBA)
	# where X is east, Y is north, Z is up,
	# and 0, 0, 0 is the center
	# Note: this conversion is NOT exact, since it doesn't take into account
	# Earth's ellipticity!  But it's close enough.
	if telescope == 'VLBA' and not log:
		antLons, antLats = [[pos[i] for pos in antWgs84s] for i in ['m0','m1']]
		antXs = [qa.convert(lon, 'deg')['value'] for lon in antLons]
		antYs = [qa.convert(lat, 'deg')['value'] for lat in antLats]
	else:
		antLons, antLats = [np.array( [pos[i]['value']
			for pos in antWgs84s]) for i in ['m0','m1']]
		radE = 6370000.
		antXs = (antLons - arrayLon) * radE * np.cos(arrayLat)
		antYs = (antLats - arrayLat) * radE
	return telescope, antNames, antIdsUsed, antXs, antYs, stationNames