Beispiel #1
0
def tigger_src(src, idx):

    name = "SRC%d" % idx
    flux = ModelClasses.Polarization(float(src["int_flux"]), 0, 0, 0,
                                     I_err=float(src["err_int_flux"]))
    ra, ra_err = map(numpy.deg2rad, (float(src["ra"]), float(src["err_ra"])))
    dec, dec_err = map(numpy.deg2rad, (float(src["dec"]),
                                       float(src["err_dec"])))
    pos = ModelClasses.Position(ra, dec, ra_err=ra_err, dec_err=dec_err)
    ex, ex_err = map(numpy.deg2rad, (float(src["a"]), float(src["err_a"])))
    ey, ey_err = map(numpy.deg2rad, (float(src["b"]), float(src["err_b"])))
    pa, pa_err = map(numpy.deg2rad, (float(src["pa"]), float(src["err_pa"])))

    if ex and ey:
        shape = ModelClasses.Gaussian(
            ex, ey, pa, ex_err=ex_err, ey_err=ey_err, pa_err=pa_err)
    else:
        shape = None
    source = SkyModel.Source(name, pos, flux, shape=shape)
    # Adding source peak flux (error) as extra flux attributes for sources,
    # and to avoid null values for point sources I_peak = src["Total_flux"]
    if shape:
        source.setAttribute("I_peak", float(src["peak_flux"]))
        source.setAttribute("I_peak_err", float(src["err_peak_flux"]))
    else:
        source.setAttribute("I_peak", float(src["int_flux"]))
        source.setAttribute("I_peak_err", float(src["err_int_flux"]))

    return source
Beispiel #2
0
def load(filename, center=None, **kw):
    """Imports an AIPs clean component list file
    """
    srclist = []
    dprint(1, "importing AIPS clean component table", filename)
    # read file
    ff = open(filename)

    if center is None:
        raise ValueError("field centre must be specified")

    # now process file line-by-line
    linenum = 0
    for line in ff:
        linenum += 1
        # parse one line
        dprint(4, "read line:", line)
        ff = line.split()
        if len(ff) != 5:
            continue
        try:
            num = int(ff[0])
            dx, dy, i, i_tot = list(map(float, ff[1:]))
        except:
            continue
        try:
            # convert dx/dy to real positions
            l, m = sin(dx * ARCSEC), sin(dy * ARCSEC)
            ra, dec = lm_to_radec(l, m, *center)
            pos = ModelClasses.Position(ra, dec)
        except Exception as exc:
            print("CC %d: error converting coordinates (%s), skipping" %
                  (num, str(exc)))
            continue
        flux = ModelClasses.Flux(i)
        # now create a source object
        src = SkyModel.Source('cc%d' % num, pos, flux)
        src.setAttribute('r', math.sqrt(l * l + m * m))
        srclist.append(src)
    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    # create model
    model = ModelClasses.SkyModel(*srclist)
    # setup model center
    model.setFieldCenter(*center)
    # setup radial distances
    projection = Coordinates.Projection.SinWCS(*model.fieldCenter())
    for src in model.sources:
        l, m = projection.lm(src.pos.ra, src.pos.dec)
        src.setAttribute('r', math.sqrt(l * l + m * m))
    return model
Beispiel #3
0
def tigger_src(src, idx):

    name = "SRC%d" % idx

    flux = ModelClasses.Polarization(src["Total_flux"],
                                     0,
                                     0,
                                     0,
                                     I_err=src["E_Total_flux"])
    ra, ra_err = map(numpy.deg2rad, (src["RA"], src["E_RA"]))
    dec, dec_err = map(numpy.deg2rad, (src["DEC"], src["E_DEC"]))
    pos = ModelClasses.Position(ra, dec, ra_err=ra_err, dec_err=dec_err)
    ex, ex_err = map(numpy.deg2rad, (src["DC_Maj"], src["E_DC_Maj"]))
    ey, ey_err = map(numpy.deg2rad, (src["DC_Min"], src["E_DC_Min"]))
    pa, pa_err = map(numpy.deg2rad, (src["PA"], src["E_PA"]))

    if ex and ey:
        shape = ModelClasses.Gaussian(ex,
                                      ey,
                                      pa,
                                      ex_err=ex_err,
                                      ey_err=ey_err,
                                      pa_err=pa_err)
    else:
        shape = None
    source = SkyModel.Source(name, pos, flux, shape=shape)
    # Adding source peak flux (error) as extra flux attributes for sources,
    # and to avoid null values for point sources I_peak = src["Total_flux"]
    if shape:
        source.setAttribute("I_peak", src["Peak_flux"])
        source.setAttribute("I_peak_err", src["E_peak_flux"])
    else:
        source.setAttribute("I_peak", src["Total_flux"])
        source.setAttribute("I_peak_err", src["E_Total_flux"])

    if spi_do:
        # Check if start frequency is provided if not provided raise error.
        # It is used to define tigger source spectrum index frequency
        if freq0:
            spi, spi_err = (src['Spec_Indx'], src['E_Spec_Indx'])
            source.spectrum = ModelClasses.SpectralIndex(spi, freq0)
            source.setAttribute('spi_error', spi_err)
        else:
            raise RuntimeError("No start frequency (freq0) provided.")
    return source
Beispiel #4
0
def load(filename, center=None, **kw):
    """Imports an AIPS clean component list from FITS table
    """
    srclist = []
    dprint(1, "importing AIPS clean component FITS table", filename)
    # read file
    ff = pyfits.open(filename)

    if center is None:
        hdr = ff[0].header
        ra = hdr['CRVAL1'] * _units[hdr.get('CUNIT1', 'DEG').strip()]
        dec = hdr['CRVAL2'] * _units[hdr.get('CUNIT2', 'DEG').strip()]

        print("Using FITS image centre (%.4f, %.4f deg) as field centre" %
              (ra / DEG, dec / DEG))
        center = ra, dec

    # now process file line-by-line
    cclist = ff[1].data
    hdr = ff[1].header
    ux = _units[hdr.get('TUNIT2', 'DEG').strip()]
    uy = _units[hdr.get('TUNIT3', 'DEG').strip()]
    for num, ccrec in enumerate(cclist):
        stokes_i, dx, dy = list(map(float, ccrec))
        # convert dx/dy to real positions
        l, m = sin(dx * ux), sin(dy * uy)
        ra, dec = lm_to_radec(l, m, *center)
        pos = ModelClasses.Position(ra, dec)
        flux = ModelClasses.Flux(stokes_i)
        # now create a source object
        src = SkyModel.Source('cc%d' % num, pos, flux)
        src.setAttribute('r', math.sqrt(l * l + m * m))
        srclist.append(src)
    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    # create model
    model = ModelClasses.SkyModel(*srclist)
    # setup model center
    model.setFieldCenter(*center)
    # setup radial distances
    projection = Coordinates.Projection.SinWCS(*model.fieldCenter())
    for src in model.sources:
        l, m = projection.lm(src.pos.ra, src.pos.dec)
        src.setAttribute('r', math.sqrt(l * l + m * m))
    return model
Beispiel #5
0
def load (filename,center=None,**kw):
  """Imports an AIPs clean component list file
  """
  srclist = [];
  dprint(1,"importing AIPS clean component table",filename);
  # read file
  ff = file(filename);
  
  if center is None:
    raise ValueError,"field centre must be specified";

  # now process file line-by-line
  linenum = 0;
  for line in ff:
    linenum += 1;
    # parse one line
    dprint(4,"read line:",line);
    ff = line.split();
    if len(ff) != 5:
      continue;
    try:
      num = int(ff[0]);
      dx,dy,i,i_tot = map(float,ff[1:]);
    except:
      continue;
    try:
      # convert dx/dy to real positions
      l,m = sin(dx*ARCSEC),sin(dy*ARCSEC);
      ra,dec = lm_to_radec(l,m,*center);
      pos = ModelClasses.Position(ra,dec);
    except Exception,exc:
      print "CC %d: error converting coordinates (%s), skipping"%(num,str(exc));
      continue;
    flux = ModelClasses.Flux(i);
    # now create a source object
    src = SkyModel.Source('cc%d'%num,pos,flux);
    src.setAttribute('r',math.sqrt(l*l+m*m));
    srclist.append(src);
Beispiel #6
0
def load(filename, center=None, **kw):
    """Imports an AIPS clean component list from FITS table
  """
    srclist = []
    dprint(1, "importing AIPS clean component FITS table", filename)
    # read file
    ff = pyfits.open(filename)

    if center is None:
        ra = ff[0].header['CRVAL1']
        dec = ff[0].header['CRVAL2']
        print "Using FITS image centre (%.4f, %.4f deg) as field centre" % (
            ra, dec)
        center = ra * DEG, dec * DEG

    # now process file line-by-line
    cclist = ff[1].data
    for num, ccrec in enumerate(cclist):
        stokes_i, dx, dy = map(float, ccrec)
        # convert dx/dy to real positions
        l, m = sin(dx * ARCSEC), sin(dy * ARCSEC)
        ra, dec = lm_to_radec(l, m, *center)
        pos = ModelClasses.Position(ra, dec)
        flux = ModelClasses.Flux(stokes_i)
        # now create a source object
        src = SkyModel.Source('cc%d' % num, pos, flux)
        src.setAttribute('r', math.sqrt(l * l + m * m))
        srclist.append(src)
    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    # create model
    model = ModelClasses.SkyModel(*srclist)
    # setup model center
    model.setFieldCenter(*center)
    # setup radial distances
    projection = Coordinates.Projection.SinWCS(*model.fieldCenter())
    return model
Beispiel #7
0
def tigger_src(src, idx):

    name = "SRC%d" % idx
    flux = ModelClasses.Polarization(src["f_int"], 0, 0, 0)
    ra = numpy.deg2rad(src["ra"])
    dec = numpy.deg2rad(src["dec"])
    pos = ModelClasses.Position(ra, dec)
    ex = numpy.deg2rad(src["ell_maj"])
    ey = numpy.deg2rad(src["ell_min"])
    pa = numpy.deg2rad(src["ell_pa"])

    if ex and ey:
        shape = ModelClasses.Gaussian(ex, ey, pa)
    else:
        shape = None
    source = SkyModel.Source(name, pos, flux, shape=shape)
    # Adding source peak flux (error) as extra flux attributes for sources,
    # and to avoid null values for point sources I_peak = src["Total_flux"]
    if shape:
        source.setAttribute("I_peak", float(src["f_peak"]))
    else:
        source.setAttribute("I_peak", float(src["f_int"]))

    return source
Beispiel #8
0
 def accept(self):
     """Tries to make a brick, and closes the dialog if successful."""
     sources = [
         src for src in self.model.sources
         if src.selected and src.typecode == 'pnt'
     ]
     filename = self.wfile.filename()
     if not self._fileSelected(filename):
         return
     # get PB expression
     pbfunc = None
     if self.wpb_apply.isChecked():
         pbexp = str(self.wpb_exp.text())
         try:
             pbfunc = eval("lambda r,fq:" + pbexp)
         except Exception as err:
             QMessageBox.warning(
                 self, "Error parsing PB experssion",
                 "Error parsing primary beam expression %s: %s" %
                 (pbexp, str(err)))
             return
     # get frequency
     freq = str(self.wfreq.text())
     freq = float(freq) * 1e+6 if freq else None
     # get pad factor
     pad = str(self.wpad.text())
     pad = max(float(pad), 1) if pad else 1
     # read fits file
     busy = BusyIndicator()
     try:
         input_hdu = pyfits.open(filename)[0]
     except Exception as err:
         busy = None
         QMessageBox.warning(
             self, "Error reading FITS",
             "Error reading FITS file %s: %s" % (filename, str(err)))
         return
     # reset data if asked to
     if self.woverwrite.isChecked():
         input_hdu.data[...] = 0
     # insert sources
     Imaging.restoreSources(input_hdu,
                            sources,
                            0,
                            primary_beam=pbfunc,
                            freq=freq)
     # save fits file
     try:
         # pyfits seems to produce an exception:
         #         TypeError: formatwarning() takes exactly 4 arguments (5 given)
         # when attempting to overwrite a file. As a workaround, remove the file first.
         if os.path.exists(filename):
             os.remove(filename)
         input_hdu.writeto(filename)
     except Exception as err:
         traceback.print_exc()
         busy = None
         QMessageBox.warning(
             self, "Error writing FITS",
             "Error writing FITS file %s: %s" % (filename, str(err)))
         return
     changed = False
     sources = self.model.sources
     # remove sources from model if asked to
     if self.wdel.isChecked():
         sources = [
             src for src in sources
             if not (src.selected and src.typecode == 'pnt')
         ]
         changed = True
     # add image to model if asked to
     if self.wadd.isChecked():
         hdr = input_hdu.header
         # get image parameters
         max_flux = float(input_hdu.data.max())
         wcs = WCS(hdr, mode='pyfits')
         # Get reference pixel coordinates
         # wcs.getCentreWCSCoords() doesn't work, as that gives us the middle of the image
         # So scan the header to get the CRPIX values
         ra0 = dec0 = 1
         for iaxis in range(hdr['NAXIS']):
             axs = str(iaxis + 1)
             name = hdr.get('CTYPE' + axs, axs).upper()
             if name.startswith("RA"):
                 ra0 = hdr.get('CRPIX' + axs, 1) - 1
             elif name.startswith("DEC"):
                 dec0 = hdr.get('CRPIX' + axs, 1) - 1
         # convert pixel to degrees
         ra0, dec0 = wcs.pix2wcs(ra0, dec0)
         ra0 *= DEG
         dec0 *= DEG
         sx, sy = wcs.getHalfSizeDeg()
         sx *= DEG
         sy *= DEG
         nx, ny = input_hdu.data.shape[-1:-3:-1]
         # check if this image is already contained in the model
         for src in sources:
             if isinstance(getattr(src, 'shape', None),
                           ModelClasses.FITSImage) and os.path.samefile(
                               src.shape.filename, filename):
                 # update source parameters
                 src.pos.ra, src.pos.dec = ra0, dec0
                 src.flux.I = max_flux
                 src.shape.ex, src.shape.ey = sx, sy
                 src.shape.nx, src.shape.ny = nx, ny
                 src.shape.pad = pad
                 break
         # not contained, make new source object
         else:
             pos = ModelClasses.Position(ra0, dec0)
             flux = ModelClasses.Flux(max_flux)
             shape = ModelClasses.FITSImage(sx,
                                            sy,
                                            0,
                                            os.path.basename(filename),
                                            nx,
                                            ny,
                                            pad=pad)
             img_src = SkyModel.Source(os.path.splitext(
                 os.path.basename(filename))[0],
                                       pos,
                                       flux,
                                       shape=shape)
             sources.append(img_src)
         changed = True
     if changed:
         self.model.setSources(sources)
         self.model.emitUpdate(SkyModel.SkyModel.UpdateAll, origin=self)
     self.parent().showMessage("Wrote %d sources to FITS file %s" %
                               (len(sources), filename))
     busy = None
     return QDialog.accept(self)
Beispiel #9
0
def load(filename, import_src=True, import_cc=True, min_extent=0, **kw):
    """Imports a NEWSTAR MDL file.
    min_extent is minimal source extent (in radians), above which a source will be treated as a Gaussian rather than a point component.
    import_src=False causes source components to be omitted
    import_cc=False causes clean components to be omitted
    """
    srclist = []
    dprint(1, "importing NEWSTAR file", filename)
    # build the LSM from a NewStar .MDL model file
    # if only_cleancomp=True, only clean components are used to build the LSM
    # if no_cleancomp=True, no clean components are used to build the LSM
    ff = open(filename, mode="rb")

    ### read GFH and MDH headers -- 512 bytes
    try:
        gfh = numpy.fromfile(ff, dtype=numpy.uint8, count=512)
        mdh = numpy.fromfile(ff, dtype=numpy.uint8, count=64)
        # parse headers
        ftype, fhlen, fver, crdate, crtime, rrdate, rrtime, rcount, nname = parseGFH(
            gfh)
        if ftype != ".MDL":
            raise TypeError
        maxlin, modptr, nsources, mtype, mepoch, ra0, dec0, freq0 = parseMDH(
            mdh)

        beam_const = 65 * 1e-9 * freq0

        ## temp dict to hold unique nodenames
        unamedict = {}
        ### Models -- 56 bytes
        for ii in range(0, nsources):
            mdl = numpy.fromfile(ff, dtype=numpy.uint8, count=56)

            ### source parameters
            sI, ll, mm, id, sQ, sU, sV, eX, eY, eP, SI, RM = struct.unpack(
                'fffiffffffff', mdl[0:48])
            ### type bits
            bit1, bit2 = struct.unpack('BB', mdl[52:54])

            # convert fluxes
            sI *= 0.005  # convert from WU to Jy (1WU=5mJy)
            sQ *= sI
            sU *= sI
            sV *= sI

            # Interpret bitflags 1: bit 0= extended; bit 1= Q|U|V <>0 and no longer used according to Wim
            fl_ext = bit1 & 1
            # Interpret bitflags 2: bit 0= clean component; bit 3= beamed
            fl_cc = bit2 & 1
            fl_beamed = bit2 & 8

            ### extended source params: in arcsec, so multiply by ???
            if fl_ext:
                ## the procedure is NMOEXT in nscan/nmoext.for
                if eP == 0 and eX == eY:
                    r0 = 0
                else:
                    r0 = .5 * math.atan2(-eP, eY - eX)
                r1 = math.sqrt(eP * eP + (eX - eY) * (eX - eY))
                r2 = eX + eY
                eX = 2 * math.sqrt(abs(0.5 * (r2 + r1)))
                eY = 2 * math.sqrt(abs(0.5 * (r2 - r1)))
                eP = r0

            # NEWSTAR MDL lists might have same source twice if they are
            # clean components, so make a unique name for them
            bname = 'N' + str(id)
            if bname in unamedict:
                uniqname = bname + '_' + str(unamedict[bname])
                unamedict[bname] += 1
            else:
                uniqname = bname
                unamedict[bname] = 1
            # compose source information
            pos = ModelClasses.Position(*lm_ncp_to_radec(ra0, dec0, ll, mm))
            flux = ModelClasses.PolarizationWithRM(sI, sQ, sU, sV, RM, freq0)
            spectrum = ModelClasses.SpectralIndex(SI, freq0)
            tags = {}
            # work out beam gain and apparent flux
            tags['_lm_ncp'] = (ll, mm)
            tags['_newstar_r'] = tags['r'] = r = math.sqrt(ll * ll + mm * mm)
            tags['newstar_beamgain'] = bg = max(
                math.cos(beam_const * r)**6, .01)
            tags['newstar_id'] = id
            if fl_beamed:
                tags['Iapp'] = sI * bg
                tags['newstar_beamed'] = True
                tags['flux_intrinsic'] = True
            else:
                tags['flux_apparent'] = True
            # make some tags based on model flags
            if fl_cc:
                tags['newstar_cc'] = True
            # make shape if extended
            if fl_ext and max(eX, eY) >= min_extent:
                shape = ModelClasses.Gaussian(eX, eY, eP)
            else:
                shape = None
            # compute apparent flux
            src = SkyModel.Source(uniqname,
                                  pos,
                                  flux,
                                  shape=shape,
                                  spectrum=spectrum,
                                  **tags)
            srclist.append(src)
    except:
        traceback.print_exc()
        raise TypeError("%s does not appear to be a valid NEWSTAR MDL file" %
                        filename)

    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    return ModelClasses.SkyModel(ra0=ra0,
                                 dec0=dec0,
                                 freq0=freq0,
                                 pbexp='max(cos(65*1e-9*fq*r)**6,.01)',
                                 *srclist)
Beispiel #10
0
def load(filename, format=None, freq0=None, center_on_brightest=False, min_extent=0, verbose=0, **kw):
    """Imports an ASCII table
    The 'format' argument can be either a dict (such as the DefaultDMSFormat dict above), or a string such as DefaultDMSFormatString.
    (Other possible field names are "ra_d", "ra_rad", "dec_rad", "dec_sign".)
    If None is specified, DefaultDMSFormat is used.
    The 'freq0' argument supplies a default reference frequency (if one is not contained in the file.)
    If 'center_on_brightest' is True, the mpodel field center will be set to the brightest source.
    'min_extent' is minimal source extent (in radians), above which a source will be treated as a Gaussian rather than a point component.
    """
    srclist = []
    dprint(1, "importing ASCII DMS file", filename)
    # brightest source and its coordinates
    maxbright = 0
    brightest_name = radec0 = None

    # Get column number associated with field from format dict, as well as the error
    # column number. Returns tuple of indices, with None index indicating no such column
    def get_field(name):
        return format.get(name, None), format.get(name + "_err", None)

    # Get column number associated with field from format dict, as well as the error
    # column number. Field is an angle thus will be suffixed with _{rad,d,h,m,s}.
    # Returns tuple of
    #     column,scale,err_column,err_scale
    # with None index indicating no such column. Scale is scaling factor to convert
    # quantity in column to radians
    def get_ang_field(name, units=ANGULAR_UNITS):
        column = err_column = colunit = errunit = None
        units = units or ANGULAR_UNITS
        for unit, scale in units.items():
            if column is None:
                column = format.get("%s_%s" % (name, unit))
                if column is not None:
                    colunit = scale
            if err_column is None:
                err_column = format.get("%s_err_%s" % (name, unit))
                if err_column is not None:
                    errunit = scale
        return column, colunit, err_column, errunit

    # helper function: returns element #num from the fields list, multiplied by scale, or None if no such field
    def getval(num, scale=1):
        return None if (num is None or len(fields) <= num) else float(fields[num]) * scale

    # now process file line-by-line
    linenum = 0
    format_str = ''
    for line in open(filename):
        # for the first line, figure out the file format
        if not linenum:
            if not format and line.startswith("#format:"):
                format = line[len("#format:"):].strip()
                dprint(1, "file contains format header:", format)
            # set default format
            if format is None:
                format = DefaultDMSFormatString
            # is the format a string rather than a dict? Turn it into a dict then
            if isinstance(format, str):
                format_str = format
                # make list of fieldname,fieldnumber tuples
                fields = [(field, i) for i, field in enumerate(format.split())]
                if not fields:
                    raise ValueError("illegal format string in file: '%s'" % format)
                # last fieldname can end with ... to indicate that it absorbs the rest of the line
                if fields[-1][0].endswith('...'):
                    fields[-1] = (fields[-1][0][:-3], slice(fields[-1][1], None))
                # make format dict
                format = dict(fields)
            elif not isinstance(format, dict):
                raise TypeError("invalid 'format' argument of type %s" % (type(format)))
                # nf = max(format.itervalues())+1
                # fields = ['---']*nf
                # for field,number in format.iteritems():
                #   fields[number] = field
                # format_str = " ".join(fields)
            # get list of custom attributes from format
            custom_attrs = []
            for name, col in format.items():
                if name.startswith(":"):
                    m = re.match("^:(bool|int|float|complex|str):([\w]+)$", name)
                    if not m:
                        raise TypeError("invalid field specification '%s' in format string" % name)
                    custom_attrs.append((eval(m.group(1)), m.group(2), col))
            # get minimum necessary fields from format
            name_field = format.get('name', None)
            # flux
            i_field, i_err_field = get_field("i")
            if i_field is None:
                raise ValueError("ASCII format specification lacks mandatory flux field ('i')")
            # main RA field
            ra_field, ra_scale, ra_err_field, ra_err_scale = get_ang_field('ra', ANGULAR_UNITS_RA)
            if ra_field is None:
                raise ValueError("ASCII format specification lacks mandatory Right Ascension field ('ra_h', 'ra_d' or 'ra_rad')")
            # main Dec field
            dec_field, dec_scale, dec_err_field, dec_err_scale = get_ang_field('dec', ANGULAR_UNITS_DEC)
            if dec_field is None:
                raise ValueError("ASCII format specification lacks mandatory Declination field ('dec_d' or 'dec_rad')")
            # polarization as QUV
            quv_fields = [get_field(x) for x in ['q', 'u', 'v']]
            # linear polarization as fraction and angle
            polfrac_field = format.get('pol_frac', None)
            if polfrac_field is not None:
                polpa_field, polpa_scale = format.get('pol_pa_d', None), (math.pi / 180)
                if not polpa_field is not None:
                    polpa_field, polpa_scale = format.get('pol_pa_rad', None), 1
            # fields for extent parameters
            extent_fields = [get_ang_field(x, ANGULAR_UNITS) for x in ('emaj', 'emin', 'pa')]
            # all three must be present, else ignore
            if any([x[0] is None for x in extent_fields]):
                extent_fields = None
            # fields for reference freq and RM and SpI
            freq0_field = format.get('freq0', None)
            rm_field, rm_err_field = get_field('rm')
            spi_fields = [get_field('spi')] + [get_field('spi%d' % i) for i in range(2, 10)]
            tags_slice = format.get('tags', None)
        # now go on to process the line
        linenum += 1
        try:
            # strip whitespace
            line = line.strip()
            dprintf(4, "%s:%d: read line '%s'\n", filename, linenum, line)
            # skip empty or commented lines
            if not line or line[0] == '#':
                continue
            # split (at whitespace) into fields
            fields = line.split()
            # get  name
            name = fields[name_field] if name_field is not None else str(len(srclist) + 1)
            i = getval(i_field)
            i_err = getval(i_err_field)
            # get position: RA
            ra = getval(ra_field)
            ra_err = getval(ra_err_field, ra_scale)
            if 'ra_m' in format:
                ra += float(fields[format['ra_m']]) / 60.
            if 'ra_s' in format:
                ra += float(fields[format['ra_s']]) / 3600.
            ra *= ra_scale
            # position: Dec. Separate treatment of sign
            dec = abs(getval(dec_field))
            dec_err = getval(dec_err_field, dec_scale)
            if 'dec_m' in format:
                dec += float(fields[format['dec_m']]) / 60.
            if 'dec_s' in format:
                dec += float(fields[format['dec_s']]) / 3600.
            if fields[format.get('dec_sign', dec_field)][0] == '-':
                dec = -dec
            dec *= dec_scale
            # for up position object
            pos = ModelClasses.Position(ra, dec, ra_err=ra_err, dec_err=dec_err)
            # see if we have freq0

            # Use explicitly provided reference frequency for this source if available
            f0 = None
            if freq0_field is not None:
                try:
                    f0 = float(fields[freq0_field])
                    # If no default reference frequency for the model was supplied,
                    # initialise from first source with a reference frequency
                    if freq0 is None:
                        freq0 = f0
                        dprint(0, "Set default freq0 to %s "
                                  "from source on line %s." % (f0, linenum))

                except IndexError:
                    f0 = None

            # Otherwise use default reference frequency (derived from args
            # or first reference frequency found in source)
            if f0 is None and freq0 is not None:
                f0 = freq0

            # see if we have Q/U/V
            (q, q_err), (u, u_err), (v, v_err) = [(getval(x), getval(x_err)) for x, x_err in quv_fields]
            if polfrac_field is not None:
                pf = fields[polfrac_field]
                pf = float(pf[:-1]) / 100 if pf.endswith("%") else float(pf)
                ppa = float(fields[polpa_field]) * polpa_scale if polpa_field is not None else 0
                q = i * pf * math.cos(2 * ppa)
                u = i * pf * math.sin(2 * ppa)
                v = 0
            # see if we have RM as well. Create flux object (unpolarized, polarized, polarized w/RM)
            rm, rm_err = getval(rm_field), getval(rm_err_field)
            if q is None:
                flux = ModelClasses.Polarization(i, 0, 0, 0, I_err=i_err)
            elif f0 is None or rm is None:
                flux = ModelClasses.Polarization(i, q, u, v, I_err=i_err, Q_err=q_err, U_err=u_err, V_err=v_err)
            else:
                flux = ModelClasses.PolarizationWithRM(i, q, u, v, rm, f0, I_err=i_err, Q_err=q_err, U_err=u_err,
                                                       V_err=v_err, rm_err=rm_err)
            # see if we have a spectral index
            if f0 is None:
                spectrum = None
            else:
                spi = [getval(x) for x, xerr in spi_fields]
                spi_err = [getval(xerr) for x, xerr in spi_fields]
                dprint(4, name, "spi is", spi, "err is", spi_err)
                # if any higher-order spectral terms are specified, include them here but trim off all trailing zeroes
                while spi and not spi[-1]:
                    del spi[-1]
                    del spi_err[-1]
                if not spi:
                    spectrum = None
                elif len(spi) == 1:
                    spectrum = ModelClasses.SpectralIndex(spi[0], f0)
                    if spi_err[0] is not None:
                        spectrum.spi_err = spi_err[0]
                else:
                    spectrum = ModelClasses.SpectralIndex(spi, f0)
                    if any([x is not None for x in spi_err]):
                        spectrum.spi_err = spi_err
            # see if we have extent parameters
            ex = ey = pa = 0
            if extent_fields:
                ex, ey, pa = [(getval(x[0], x[1]) or 0) for x in extent_fields]
                extent_errors = [getval(x[2], x[3]) for x in extent_fields]
            # form up shape object
            if (ex or ey) and max(ex, ey) >= min_extent:
                shape = ModelClasses.Gaussian(ex, ey, pa)
                for ifield, field in enumerate(['ex', 'ey', 'pa']):
                    if extent_errors[ifield] is not None:
                        shape.setAttribute(field + "_err", extent_errors[ifield])
            else:
                shape = None
            # get tags
            tagdict = {}
            if tags_slice:
                try:
                    tags = fields[tags_slice]
                except IndexError:
                    pass
                for tagstr1 in tags:
                    for tagstr in tagstr1.split(","):
                        if tagstr[0] == "+":
                            tagname, value = tagstr[1:], True
                        elif tagstr[0] == "-":
                            tagname, value = tagstr[1:], False
                        elif "=" in tagstr:
                            tagname, value = tagstr.split("=", 1)
                            if value[0] in "'\"" and value[-1] in "'\"":
                                value = value[1:-1]
                            else:
                                try:
                                    value = float(value)
                                except:
                                    continue
                        else:
                            tagname, value = tagstr, True
                        tagdict[tagname] = value
            # OK, now form up the source object
            # now create a source object
            dprint(3, name, ra, dec, i, q, u, v)
            src = SkyModel.Source(name, pos, flux, shape=shape, spectrum=spectrum, **tagdict)
            # get custom attributes
            for type_, attr, column in custom_attrs:
                if column is not None and len(fields) > column:
                    src.setAttribute(attr, type_(fields[column]))
            # add to source list
            srclist.append(src)
            # check if it's the brightest
            brightness = src.brightness()
            if brightness > maxbright:
                maxbright = brightness
                brightest_name = src.name
                radec0 = ra, dec
        except:
            dprintf(0, "%s:%d: %s, skipping\n", filename, linenum, str(sys.exc_info()[1]))
            if verbose:
                raise
    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    # create model
    model = ModelClasses.SkyModel(*srclist)
    if freq0 is not None:
        model.setRefFreq(freq0)
    # set model format
    model.setAttribute("ASCII_Format", format_str)
    # setup model center
    if center_on_brightest and radec0:
        dprintf(2, "brightest source is %s (%g Jy) at %f,%f\n", brightest_name, maxbright, *radec0)
        model.setFieldCenter(*radec0)
    # setup radial distances
    projection = Coordinates.Projection.SinWCS(*model.fieldCenter())
    for src in model.sources:
        l, m = projection.lm(src.pos.ra, src.pos.dec)
        src.setAttribute('r', math.sqrt(l * l + m * m))
    return model
Beispiel #11
0
class AddBrickDialog(QDialog):
    def __init__(self, parent, modal=True, flags=Qt.WindowFlags()):
        QDialog.__init__(self, parent, flags)
        self.setModal(modal)
        self.setWindowTitle("Add FITS brick")
        lo = QVBoxLayout(self)
        lo.setMargin(10)
        lo.setSpacing(5)
        # file selector
        self.wfile = FileSelector(self,
                                  label="FITS filename:",
                                  dialog_label="FITS file",
                                  default_suffix="fits",
                                  file_types="FITS files (*.fits *.FITS)",
                                  file_mode=QFileDialog.ExistingFile)
        lo.addWidget(self.wfile)
        # overwrite or add mode
        lo1 = QGridLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        lo1.addWidget(QLabel("Padding factor:", self), 0, 0)
        self.wpad = QLineEdit("2", self)
        self.wpad.setValidator(QDoubleValidator(self))
        lo1.addWidget(self.wpad, 0, 1)
        lo1.addWidget(QLabel("Assign source name:", self), 1, 0)
        self.wname = QLineEdit(self)
        lo1.addWidget(self.wname, 1, 1)
        # OK/cancel buttons
        lo.addSpacing(10)
        lo2 = QHBoxLayout()
        lo.addLayout(lo2)
        lo2.setContentsMargins(0, 0, 0, 0)
        lo2.setMargin(5)
        self.wokbtn = QPushButton("OK", self)
        self.wokbtn.setMinimumWidth(128)
        QObject.connect(self.wokbtn, SIGNAL("clicked()"), self.accept)
        self.wokbtn.setEnabled(False)
        cancelbtn = QPushButton("Cancel", self)
        cancelbtn.setMinimumWidth(128)
        QObject.connect(cancelbtn, SIGNAL("clicked()"), self.reject)
        lo2.addWidget(self.wokbtn)
        lo2.addStretch(1)
        lo2.addWidget(cancelbtn)
        self.setMinimumWidth(384)
        # signals
        QObject.connect(self.wfile, SIGNAL("filenameSelected"),
                        self._fileSelected)
        # internal state
        self.qerrmsg = QErrorMessage(self)

    def setModel(self, model):
        self.model = model
        if model.filename():
            self._model_dir = os.path.dirname(os.path.abspath(
                model.filename()))
        else:
            self._model_dir = os.path.abspath('.')
        self.wfile.setDirectory(self._model_dir)
        self._fileSelected(self.wfile.filename(), quiet=True)

    def _fileSelected(self, filename, quiet=False):
        self.wokbtn.setEnabled(False)
        if not filename:
            return None
        # check that filename matches model
        if not os.path.samefile(self._model_dir, os.path.dirname(filename)):
            self.wfile.setFilename('')
            if not quiet:
                QMessageBox.warning(
                    self, "Directory mismatch",
                    """<P>The FITS file must reside in the same directory
          as the current sky model.</P>""")
            self.wfile.setDirectory(self._model_dir)
            return None
        # if filename is not in model already, enable the "add to model" control
        for src in self.model.sources:
            if isinstance(getattr(src, 'shape', None), ModelClasses.FITSImage):
                if os.path.exists(src.shape.filename) and os.path.samefile(
                        src.shape.filename, filename):
                    if not quiet:
                        QMessageBox.warning(
                            self, "Already in model",
                            "This FITS brick is already present in the model.")
                    self.wfile.setFilename('')
                    return None
        if not str(self.wname.text()):
            self.wname.setText(
                os.path.splitext(os.path.basename(str(filename)))[0])
        self.wokbtn.setEnabled(True)
        return filename

    def accept(self):
        """Tries to add brick, and closes the dialog if successful."""
        filename = self.wfile.filename()
        # read fits file
        busy = BusyIndicator()
        try:
            input_hdu = pyfits.open(filename)[0]
        except Exception, err:
            busy = None
            QMessageBox.warning(
                self, "Error reading FITS",
                "Error reading FITS file %s: %s" % (filename, str(err)))
            return
        # check name
        srcname = str(self.wname.text()) or os.path.splitext(
            os.path.basename(str(filename)))[0]
        if srcname in set([src.name for src in self.model.sources]):
            QMessageBox.warning(
                self, "Already in model",
                "<p>The model already contains a source named '%s'. Please select a different name.</p>"
                % srcname)
            return
        # get image parameters
        hdr = input_hdu.header
        max_flux = float(input_hdu.data.max())
        wcs = WCS(hdr, mode='pyfits')
        # Get reference pixel coordinates
        # wcs.getCentreWCSCoords() doesn't work, as that gives us the middle of the image
        # So scan the header to get the CRPIX values
        ra0 = dec0 = 1
        for iaxis in range(hdr['NAXIS']):
            axs = str(iaxis + 1)
            name = hdr.get('CTYPE' + axs, axs).upper()
            if name.startswith("RA"):
                ra0 = hdr.get('CRPIX' + axs, 1) - 1
            elif name.startswith("DEC"):
                dec0 = hdr.get('CRPIX' + axs, 1) - 1
        # convert pixel to degrees


#    print ra0,dec0;
        ra0, dec0 = wcs.pix2wcs(ra0, dec0)
        ra0 *= DEG
        dec0 *= DEG
        #    print ModelClasses.Position.ra_hms_static(ra0);
        #    print ModelClasses.Position.dec_sdms_static(dec0);
        sx, sy = wcs.getHalfSizeDeg()
        sx *= DEG
        sy *= DEG
        nx, ny = input_hdu.data.shape[-1:-3:-1]
        pos = ModelClasses.Position(ra0, dec0)
        flux = ModelClasses.Flux(max_flux)
        shape = ModelClasses.FITSImage(sx,
                                       sy,
                                       0,
                                       os.path.basename(filename),
                                       nx,
                                       ny,
                                       pad=float(str(self.wpad.text()) or "1"))
        img_src = SkyModel.Source(srcname, pos, flux, shape=shape)
        self.model.setSources(self.model.sources + [img_src])
        self.model.emitUpdate(SkyModel.SkyModel.UpdateAll, origin=self)
        busy = None
        return QDialog.accept(self)
Beispiel #12
0
    def params(self, modelfits):

        # reads in source finder output
        with pyfits.open(modelfits) as hdu:
            data = hdu[1].data

        tfile = tempfile.NamedTemporaryFile(suffix=".txt")
        tfile.flush()

        # writes a catalogue in a temporaty txt file
        with open(tfile.name, "w") as std:
            std.write("#format:name ra_rad dec_rad i emaj_r emin_r pa_r\n")

        model = Tigger.load(tfile.name)  # open a tmp. file

        peak, total, area, loc, corr = [], [], [], [], []
        for i in range(len(data)):
            flux = data["Total_flux"][i]
            dc_emaj, dc_emin = data["DC_Maj"][i], data["DC_Min"][i]
            ra, dec = data["RA"][i], data["DEC"][i]
            pa = data["DC_PA"][i]
            name = "SRC%d" % i
            peak_flux = data["Peak_flux"][i]

            posrd = ModelClasses.Position(numpy.deg2rad(ra),
                                          numpy.deg2rad(dec))
            flux_I = ModelClasses.Polarization(flux, 0, 0, 0)
            if dc_emaj == 0 and dc_emin == 0:
                shape = None
            else:
                shape = ModelClasses.Gaussian(numpy.deg2rad(dc_emaj),
                                              numpy.deg2rad(dc_emin),
                                              numpy.deg2rad(pa))

            srs = SkyModel.Source(name, posrd, flux_I, shape=shape)

            # using convolved maj and min for reliability estimate
            emaj, emin = data["Maj"][i], data["Min"][i]

            # area: find ex and ey if are 0 assign beam size
            if emaj or emin == 0:
                srcarea = math.pi * (numpy.rad2deg(self.bmaj)) * pow(3600.0, 2) *\
                       (numpy.rad2deg(self.bmin))
            if emaj and emin > 0:
                srcarea = emaj * emin * math.pi * pow(3600.0, 2)  # arcsecond

            # only accepts sources with flux > 0 and not nan RA and DEC
            # and local variance
            pos = [self.wcs.wcs2pix(*(ra, dec))
                   ][0]  #positions from deg to pixel

            with pyfits.open(self.negimage) as hdu:
                negdata = utils.image_data(hdu[0].data)

            if flux > 0 and peak_flux > 0 and not math.isnan(float(ra))\
                and not math.isnan(float(dec)):

                local = utils.compute_local_variance(negdata, pos,
                                                     self.locstep)

                srs.setAttribute("local_variance", local)

                if not math.isnan(float(local)) or local > 0:
                    if self.psfname:
                        pdata, psf = utils.compute_psf_correlation(
                            self.imagename, self.psfname, pos, self.cfstep)

                        if len(pdata) == len(psf):
                            c_region = numpy.corrcoef((pdata, psf))
                            cf = (numpy.diag((numpy.rot90(c_region))**
                                             2).sum())**0.5 / 2**0.5

                            srs.setAttribute("correlation_factor", cf)
                            corr.append(cf)
                            model.sources.append(srs)
                            peak.append(peak_flux)
                            total.append(flux)
                            area.append(srcarea)
                            loc.append(local)
                    else:
                        model.sources.append(srs)
                        peak.append(peak_flux)
                        total.append(flux)
                        area.append(srcarea)
                        loc.append(local)

        labels = dict(size=(0, "Log$_{10}$(Source area)"),
                      peak=(1, "Log$_{10}$( Peak flux [Jy] )"),
                      tot=(2, "Log$_{10}$( Total flux [Jy] )"))

        if self.do_psf_corr:
            labels.update({"coeff": (len(labels), "Log$_{10}$ (CF)")})
        if self.do_local_var:
            labels.update(
                {"local": (len(labels), "Log$_{10}$(Local Variance)")})
        if self.nearsources:
            labels.update({"near": (len(labels), "Log$_{10}$(Near Sources)")})

        nsrc = len(model.sources)
        out = numpy.zeros([nsrc, len(labels)])

        # returning parameters
        for i, src in enumerate(model.sources):

            ra, dec = src.pos.ra, src.pos.dec
            near = model.getSourcesNear(ra, dec, 5 * self.bmaj)
            nonear = len(near)
            if self.nearsources:
                src.setAttribute("neibours", nonear)

            if self.do_psf_corr and self.do_local_var and self.nearsources:
                out[i,
                    ...] = area[i], peak[i], total[i], corr[i], loc[i], nonear

            elif self.do_psf_corr and self.do_local_var and not self.nearsources:
                out[i, ...] = area[i], peak[i], total[i], corr[i], loc[i]

            elif self.do_psf_corr and self.nearsources and not self.do_local_var:
                out[i, ...] = area[i], peak[i], total[i], corr[i], nonear

            elif not self.do_psf_corr and self.do_local_var and self.nearsources:
                out[i, ...] = area[i], peak[i], total[i], loc[i], nonear

            elif self.do_psf_corr and not self.do_local_var and not self.nearsources:
                out[i, ...] = area[i], peak[i], total[i], corr[i]

            elif not self.do_psf_corr and self.do_local_var and not self.nearsources:
                out[i, ...] = area[i], peak[i], total[i], loc[i]

            elif not self.do_psf_corr and not self.do_local_var and self.nearsources:
                out[i, ...] = area[i], peak[i], total[i], nonear

            else:
                out[i, ...] = area[i], peak[i], total[i]

        # removes the rows with 0s
        removezeros = (out == 0).sum(1)
        output = out[removezeros <= 0, :]

        return model, numpy.log10(output), labels
Beispiel #13
0
 def accept(self):
     """Tries to add brick, and closes the dialog if successful."""
     filename = self.wfile.filename()
     # read fits file
     busy = BusyIndicator()
     try:
         input_hdu = pyfits.open(filename)[0]
     except Exception as err:
         busy.reset_cursor()
         QMessageBox.warning(
             self, "Error reading FITS",
             "Error reading FITS file %s: %s" % (filename, str(err)))
         return
     # check name
     srcname = str(self.wname.text()) or os.path.splitext(
         os.path.basename(str(filename)))[0]
     if srcname in set([src.name for src in self.model.sources]):
         QMessageBox.warning(
             self, "Already in model",
             "<p>The model already contains a source named '%s'. Please select a different name.</p>"
             % srcname)
         return
     # get image parameters
     hdr = input_hdu.header
     max_flux = float(input_hdu.data.max())
     wcs = WCS(hdr, mode='pyfits')
     # Get reference pixel coordinates
     # wcs.getCentreWCSCoords() doesn't work, as that gives us the middle of the image
     # So scan the header to get the CRPIX values
     ra0 = dec0 = 1
     for iaxis in range(hdr['NAXIS']):
         axs = str(iaxis + 1)
         name = hdr.get('CTYPE' + axs, axs).upper()
         if name.startswith("RA"):
             ra0 = hdr.get('CRPIX' + axs, 1) - 1
         elif name.startswith("DEC"):
             dec0 = hdr.get('CRPIX' + axs, 1) - 1
     # convert pixel to degrees
     #    print ra0,dec0
     ra0, dec0 = wcs.pix2wcs(ra0, dec0)
     ra0 *= DEG
     dec0 *= DEG
     #    print ModelClasses.Position.ra_hms_static(ra0)
     #    print ModelClasses.Position.dec_sdms_static(dec0)
     sx, sy = wcs.getHalfSizeDeg()
     sx *= DEG
     sy *= DEG
     nx, ny = input_hdu.data.shape[-1:-3:-1]
     pos = ModelClasses.Position(ra0, dec0)
     flux = ModelClasses.Flux(max_flux)
     shape = ModelClasses.FITSImage(sx,
                                    sy,
                                    0,
                                    os.path.basename(filename),
                                    nx,
                                    ny,
                                    pad=float(str(self.wpad.text()) or "1"))
     img_src = SkyModel.Source(srcname, pos, flux, shape=shape)
     self.model.setSources(self.model.sources + [img_src])
     self.model.emitUpdate(SkyModel.SkyModel.UpdateAll, origin=self)
     busy.reset_cursor()
     return QDialog.accept(self)
Beispiel #14
0
def load(filename, freq0=None, center_on_brightest=False, **kw):
    """Imports an BBS catalog file
    The 'format' argument can be either a dict (such as the DefaultDMSFormat dict above), or a string such as DefaultDMSFormatString.
    (Other possible field names are "ra_d", "ra_rad", "dec_rad", "dec_sign".)
    If None is specified, DefaultDMSFormat is used.
    The 'freq0' argument supplies a default reference frequency (if one is not contained in the file.)
    If 'center_on_brightest' is True, the mpodel field center will be set to the brightest source,
    else to the center of the first patch.
    """
    srclist = []
    dprint(1, "importing BBS source table", filename)
    # read file
    ff = open(filename)
    # first line must be a format string: extract it
    line0 = ff.readline().strip()
    match = re.match("#\s*\((.+)\)\s*=\s*format", line0)
    if not match:
        raise ValueError("line 1 is not a valid format specification")
    format_str = match.group(1)
    # create format parser from this string
    parser = CatalogParser(format_str)

    # check for mandatory fields
    for field in "Name", "Type":
        if not parser.defines(field):
            raise ValueError("Table lacks mandatory field '%s'" % field)

    maxbright = 0
    patches = []
    ref_freq = freq0

    # now process file line-by-line
    linenum = 1
    for line in ff:
        linenum += 1
        try:
            # parse one line
            dprint(4, "read line:", line)
            catline = parser.parse(line, linenum)
            if not catline:
                continue
            dprint(5, "line %d: " % linenum, catline.__dict__)
            # is it a patch record?
            patchname = getattr(catline, 'Patch', '')
            if not catline.Name:
                dprintf(2, "%s:%d: patch %s\n", filename, linenum, patchname)
                patches.append((patchname, catline.ra_rad, catline.dec_rad))
                continue
            # form up name
            name = "%s:%s" % (patchname, catline.Name) if patchname else catline.Name
            # check source type
            stype = catline.Type.upper()
            if stype not in ("POINT", "GAUSSIAN"):
                raise ValueError("unsupported source type %s" % stype)
            # see if we have freq0
            if freq0:
                f0 = freq0
            elif hasattr(catline, 'ReferenceFrequency'):
                f0 = float(catline.ReferenceFrequency or '0')
            else:
                f0 = None
            # set model refrence frequency
            if f0 is not None and ref_freq is None:
                ref_freq = f0
            # see if we have Q/U/V
            i, q, u, v = [float(getattr(catline, stokes, '0') or '0') for stokes in "IQUV"]
            # see if we have RM as well. Create flux object (unpolarized, polarized, polarized w/RM)
            if f0 is not None and hasattr(catline, 'RotationMeasure'):
                flux = ModelClasses.PolarizationWithRM(i, q, u, v, float(catline.RotationMeasure or '0'), f0)
            else:
                flux = ModelClasses.Polarization(i, q, u, v)
            # see if we have a spectral index
            if f0 is not None and hasattr(catline, 'SpectralIndex:0'):
                spectrum = ModelClasses.SpectralIndex(float(getattr(catline, 'SpectralIndex:0') or '0'), f0)
            else:
                spectrum = None
            # see if we have extent parameters
            if stype == "GAUSSIAN":
                ex = float(getattr(catline, "MajorAxis", "0") or "0")
                ey = float(getattr(catline, "MinorAxis", "0") or "0")
                pa = float(getattr(catline, "Orientation", "0") or "0")
                shape = ModelClasses.Gaussian(ex, ey, pa)
            else:
                shape = None
            # create tags
            tags = {}
            for field in "Patch", "Category":
                if hasattr(catline, field):
                    tags['BBS_%s' % field] = getattr(catline, field)
            # OK, now form up the source object
            # position
            pos = ModelClasses.Position(catline.ra_rad, catline.dec_rad)
            # now create a source object
            src = SkyModel.Source(name, pos, flux, shape=shape, spectrum=spectrum, **tags)
            srclist.append(src)
            # check if it's the brightest
            brightness = src.brightness()
            if brightness > maxbright:
                maxbright = brightness
                brightest_name = src.name
                radec0 = catline.ra_rad, catline.dec_rad
        except:
            dprintf(0, "%s:%d: %s, skipping\n", filename, linenum, str(sys.exc_info()[1]))
    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    # create model
    model = ModelClasses.SkyModel(*srclist)
    if ref_freq is not None:
        model.setRefFreq(ref_freq)
    # setup model center
    if center_on_brightest and radec0:
        dprintf(2, "setting model centre to brightest source %s (%g Jy) at %f,%f\n", brightest_name, maxbright,
                *radec0)
        model.setFieldCenter(*radec0)
    elif patches:
        name, ra, dec = patches[0]
        dprintf(2, "setting model centre to first patch %s at %f,%f\n", name, ra, dec)
        model.setFieldCenter(ra, dec)
    # map patches to model tags
    model.setAttribute("BBS_Patches", patches)
    model.setAttribute("BBS_Format", format_str)
    # setup radial distances
    projection = Coordinates.Projection.SinWCS(*model.fieldCenter())
    for src in model.sources:
        l, m = projection.lm(src.pos.ra, src.pos.dec)
        src.setAttribute('r', math.sqrt(l * l + m * m))
    return model
Beispiel #15
0
      # check if this image is already contained in the model
      for src in sources:
        if isinstance(getattr(src,'shape',None),ModelClasses.FITSImage) and os.path.samefile(src.shape.filename,filename):
          # update source parameters
          src.pos.ra,src.pos.dec = ra0,dec0;
          src.flux.I = max_flux;
          src.shape.ex,src.shape.ey = sx,sy;
          src.shape.nx,src.shape.ny = nx,ny;
          src.shape.pad = pad;
          break;
      # not contained, make new source object
      else:
        pos = ModelClasses.Position(ra0,dec0);
        flux = ModelClasses.Flux(max_flux);
        shape = ModelClasses.FITSImage(sx,sy,0,os.path.basename(filename),nx,ny,pad=pad);
        img_src = SkyModel.Source(os.path.splitext(os.path.basename(filename))[0],pos,flux,shape=shape);
        sources.append(img_src);
      changed = True;
    if changed:
      self.model.setSources(sources);
      self.model.emitUpdate(SkyModel.SkyModel.UpdateAll,origin=self);
    self.parent().showMessage("Wrote %d sources to FITS file %s"%(len(sources),filename));
    busy = None;
    return QDialog.accept(self);

def make_brick (mainwin,model):
  # check that something is selected
  if not [ src for src in model.sources if src.selected ]:
    mainwin.showErrorMessage("Cannot make FITS brick without a source selection. Please select some sources first.");
    return;
  dialog = getattr(mainwin,'_make_brick_dialog',None);
Beispiel #16
0
def load(filename,
         format=None,
         freq0=None,
         center_on_brightest=False,
         min_extent=0,
         **kw):
    """Imports an ASCII table
  The 'format' argument can be either a dict (such as the DefaultDMSFormat dict above), or a string such as DefaultDMSFormatString.
  (Other possible field names are "ra_d", "ra_rad", "dec_rad", "dec_sign".)
  If None is specified, DefaultDMSFormat is used.
  The 'freq0' argument supplies a default reference frequency (if one is not contained in the file.)
  If 'center_on_brightest' is True, the mpodel field center will be set to the brightest source.
  'min_extent' is minimal source extent (in radians), above which a source will be treated as a Gaussian rather than a point component.
  """
    srclist = []
    dprint(1, "importing ASCII DMS file", filename)
    # brightest source and its coordinates
    maxbright = 0
    brightest_name = radec0 = None

    # now process file line-by-line
    linenum = 0
    format_str = ''
    for line in file(filename):
        # for the first line, firgure out the file format
        if not linenum:
            if not format and line.startswith("#format:"):
                format = line[len("#format:"):].strip()
                dprint(1, "file contains format header:", format)
            # set default format
            if format is None:
                format = DefaultDMSFormatString
            # is the format a string rather than a dict? Turn it into a dict then
            if isinstance(format, str):
                format_str = format
                # make list of fieldname,fieldnumber tuples
                fields = [(field, i) for i, field in enumerate(format.split())]
                if not fields:
                    raise ValueError, "illegal format string in file: '%s'" % format
                # last fieldname can end with ... to indicate that it absorbs the rest of the line
                if fields[-1][0].endswith('...'):
                    fields[-1] = (fields[-1][0][:-3],
                                  slice(fields[-1][1], None))
                # make format dict
                format = dict(fields)
            elif not isinstance(format, dict):
                raise TypeError, "invalid 'format' argument of type %s" % (
                    type(format))
                nf = max(format.itervalues()) + 1
                fields = ['---'] * nf
                for field, number in format.iteritems():
                    fields[number] = field
                format_str = " ".join(fields)
            # get minimum necessary fields from format
            name_field = format.get('name', None)
            # flux
            try:
                i_field = format['i']
            except KeyError:
                raise ValueError, "ASCII format specification lacks mandatory flux field ('i')"
            # main RA field
            if 'ra_h' in format:
                ra_field, ra_scale = format['ra_h'], (math.pi / 12)
            elif 'ra_d' in format:
                ra_field, ra_scale = format['ra_d'], (math.pi / 180)
            elif 'ra_rad' in format:
                ra_field, ra_scale = format['ra_rad'], 1.
            else:
                raise ValueError, "ASCII format specification lacks mandatory Right Ascension field ('ra_h', 'ra_d' or 'ra_rad')"
            # main Dec field
            if 'dec_d' in format:
                dec_field, dec_scale = format['dec_d'], (math.pi / 180)
            elif 'dec_rad' in format:
                dec_field, dec_scale = format['dec_rad'], 1.
            else:
                raise ValueError, "ASCII format specification lacks mandatory Declination field ('dec_d' or 'dec_rad')"
            # polarization as QUV
            try:
                quv_fields = [format[x] for x in ['q', 'u', 'v']]
            except KeyError:
                quv_fields = None
            # linear polarization as fraction and angle
            polfrac_field = format.get('pol_frac', None)
            if polfrac_field is not None:
                polpa_field, polpa_scale = format.get('pol_pa_d',
                                                      None), (math.pi / 180)
                if not polpa_field is not None:
                    polpa_field, polpa_scale = format.get('pol_pa_rad',
                                                          None), 1
            # fields for extent parameters
            ext_fields = []
            for ext in 'emaj', 'emin', 'pa':
                for field, scale in (ext, 1.), (ext + "_rad",
                                                1.), (ext + '_d',
                                                      DEG), (ext + '_m', DEG /
                                                             60), (ext + '_s',
                                                                   DEG / 3600):
                    if field in format:
                        ext_fields.append((format[field], scale))
                        break
            # if not all three accumulated, ignore
            if len(ext_fields) != 3:
                ext_fields = None
            # fields for reference freq and RM and SpI
            freq0_field = format.get('freq0', None)
            rm_field = format.get('rm', None)
            spi_field = format.get('spi', None)
            spi2_field = [format.get('spi%d' % i, None) for i in range(2, 10)]
            tags_slice = format.get('tags', None)
        # now go on to process the line
        linenum += 1
        try:
            # strip whitespace
            line = line.strip()
            dprintf(4, "%s:%d: read line '%s'\n", filename, linenum, line)
            # skip empty or commented lines
            if not line or line[0] == '#':
                continue
            # split (at whitespace) into fields
            fields = line.split()
            # get  name
            name = fields[name_field] if name_field is not None else str(
                len(srclist) + 1)
            i = float(fields[i_field])
            # get position: RA
            ra = float(fields[ra_field])
            if 'ra_m' in format:
                ra += float(fields[format['ra_m']]) / 60.
            if 'ra_s' in format:
                ra += float(fields[format['ra_s']]) / 3600.
            ra *= ra_scale
            # position: Dec. Separate treatment of sign
            dec = abs(float(fields[dec_field]))
            if 'dec_m' in format:
                dec += float(fields[format['dec_m']]) / 60.
            if 'dec_s' in format:
                dec += float(fields[format['dec_s']]) / 3600.
            if fields[format.get('dec_sign', dec_field)][0] == '-':
                dec = -dec
            dec *= dec_scale
            # see if we have freq0
            try:
                f0 = freq0 or (freq0_field and float(fields[freq0_field]))
            except IndexError:
                f0 = None
            # set model refrence frequency
            if f0 is not None and freq0 is None:
                freq0 = f0
            # see if we have Q/U/V
            q = u = v = None
            if quv_fields:
                try:
                    q, u, v = map(float, [fields[x] for x in quv_fields])
                except IndexError:
                    pass
            if polfrac_field is not None:
                pf = fields[polfrac_field]
                pf = float(pf[:-1]) / 100 if pf.endswith("%") else float(pf)
                ppa = float(fields[polpa_field]
                            ) * polpa_scale if polpa_field is not None else 0
                q = i * pf * math.cos(2 * ppa)
                u = i * pf * math.sin(2 * ppa)
                v = 0
            # see if we have RM as well. Create flux object (unpolarized, polarized, polarized w/RM)
            if q is None:
                flux = ModelClasses.Polarization(i, 0, 0, 0)
            elif f0 is None or rm_field is None or rm_field >= len(fields):
                flux = ModelClasses.Polarization(i, q, u, v)
            else:
                flux = ModelClasses.PolarizationWithRM(i, q, u, v,
                                                       float(fields[rm_field]),
                                                       f0)
            # see if we have a spectral index
            if f0 is None or spi_field is None or spi_field >= len(fields):
                spectrum = None
            else:
                spi = [ float(fields[spi_field]) ] + \
                      [ (float(fields[x]) if x is not None else 0) for x in spi2_field ]
                # if any higher-order spectral terms are specified, include them here
                # but trim off all trailing zeroes
                while len(spi) > 1 and not spi[-1]:
                    del spi[-1]
                if len(spi) == 1:
                    spi = spi[0]
                spectrum = ModelClasses.SpectralIndex(spi, f0)
            # see if we have extent parameters
            ex = ey = pa = 0
            if ext_fields:
                try:
                    ex, ey, pa = [
                        float(fields[num]) * scale for num, scale in ext_fields
                    ]
                except IndexError:
                    pass
            # form up shape object
            if (ex or ey) and max(ex, ey) >= min_extent:
                shape = ModelClasses.Gaussian(ex, ey, pa)
            else:
                shape = None
            # get tags
            tagdict = {}
            if tags_slice:
                try:
                    tags = fields[tags_slice]
                except IndexError:
                    pass
                for tagstr1 in tags:
                    for tagstr in tagstr1.split(","):
                        if tagstr[0] == "+":
                            tagname, value = tagstr[1:], True
                        elif tagstr[0] == "-":
                            tagname, value = tagstr[1:], False
                        elif "=" in tagstr:
                            tagname, value = tagstr.split("=", 1)
                            if value[0] in "'\"" and value[-1] in "'\"":
                                value = value[1:-1]
                            else:
                                try:
                                    value = float(value)
                                except:
                                    continue
                        else:
                            tagname, value = tagstr, True
                        tagdict[tagname] = value

            # OK, now form up the source object
            # position
            pos = ModelClasses.Position(ra, dec)
            # now create a source object
            dprint(3, name, ra, dec, i, q, u, v)
            src = SkyModel.Source(name,
                                  pos,
                                  flux,
                                  shape=shape,
                                  spectrum=spectrum,
                                  **tagdict)
            srclist.append(src)
            # check if it's the brightest
            brightness = src.brightness()
            if brightness > maxbright:
                maxbright = brightness
                brightest_name = src.name
                radec0 = ra, dec
        except:
            dprintf(0, "%s:%d: %s, skipping\n", filename, linenum,
                    str(sys.exc_info()[1]))
    dprintf(2, "imported %d sources from file %s\n", len(srclist), filename)
    # create model
    model = ModelClasses.SkyModel(*srclist)
    if freq0 is not None:
        model.setRefFreq(freq0)
    # set model format
    model.setAttribute("ASCII_Format", format_str)
    # setup model center
    if center_on_brightest and radec0:
        dprintf(2, "brightest source is %s (%g Jy) at %f,%f\n", brightest_name,
                maxbright, *radec0)
        model.setFieldCenter(*radec0)
    # setup radial distances
    projection = Coordinates.Projection.SinWCS(*model.fieldCenter())
    for src in model.sources:
        l, m = projection.lm(src.pos.ra, src.pos.dec)
        src.setAttribute('r', math.sqrt(l * l + m * m))
    return model