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 
Esempio n. 2
0
    def __init__(self, imagename, psfname, pmodel, nmodel, local_step=10,
                 snr_thresh=40, high_corr_thresh=0.5, negdetec_region=10,
                 negatives_thresh=5, phasecenter_excl_radius=None,
                 prefix=None, loglevel=0):


        """ Determines sources that require direction-dependent (DD)
            calibration solutions.

        psfname: PSF fits data

        pmodel: Model of the positive image.

        nmodel: Model of the negative image
 
        header: The header of the input image

        snr_thresh: float, optional. Default is 40.
             Any source with 40 x the minimum SNR.

        high_corr_thresh:  float, optional. Default is 0.5.
             Sources of high PSF correlation have correlation above 0.5.

        negdetec_region:  float, optional. Default is 10.
             Region to lookup for negative detections around. In beam size.

        negative_thresh:  float, optional. Default is 5.
             The number of nearby negative detections. Sources
             with number > 5 require direction
             dependent (DD) calibration solutions.

        phasecenter_excl_region:  float (in degrees), optional.
             A radius from the phase center (in beam sizes) to exclude the sources
             from the evaluation.

        prefix: str, optional. Sets a prefix to the output directory.

        loglevel: int, optional. Default 0. Python logging.
                  0, 1, 2, 3 for info, debug, error and 
                  critical, respectively.
        """

        self.loglevel = loglevel
        self.prefix = prefix
        self.log = utils.logger(self.loglevel, prefix=self.prefix)
        #image and psf image

        self.pmodel = pmodel
        self.nmodel = nmodel
        self.psfname =  psfname
  
        self.log.info(" Loading image data")

        # tags
        self.dd_tag = "dE"

        # thresholds
        self.snr_factor = snr_thresh
        #self.localthresh = local_thresh
        self.corrthresh = high_corr_thresh
        self.negthresh = negatives_thresh
        
        with pyfits.open(imagename) as hdu:
            self.hdr = hdu[0].header
            self.data = utils.image_data(hdu[0].data)

        self.wcs = WCS(self.hdr, mode="pyfits")
        
        self.locstep = local_step

        #regions
        self.phaserad = phasecenter_excl_radius # radius from the phase center
        self.negregion =  negdetec_region # region to look for negatives
        
       # conversion
        self.bmaj = self.hdr["BMAJ"] # in degrees
        
        self.ra0 =  numpy.deg2rad(self.hdr["CRVAL1"])
        self.dec0 = numpy.deg2rad(self.hdr["CRVAL2"])
    def __init__(self, imagename, psfname=None, sourcefinder_name='pybdsm',
                 makeplots=True, do_psf_corr=True, do_local_var=True,
                 psf_corr_region=5, local_var_region=10, rel_excl_src=None, 
                 pos_smooth=2, neg_smooth=2, loglevel=0, thresh_pix=5,
                 thresh_isl=3, neg_thresh_isl=3, neg_thresh_pix=5, reset_rel=None,
                 prefix=None, do_nearsources=False, savefits=False,
                 increase_beam_cluster=False, savemask_pos=False, savemask_neg=False,
                 **kw):

        """ Takes in image and extracts sources and makes 
            reliability estimations..
           
 
        imagename: Fits image
        psfname: PSF fits image, optional. 

        sourcefinder_name: str, optional. Default 'pybdsm'.
            Uses source finder specified.

        makeplots: bool, optional. Default is True.
            Make reliability plots.

        do_psf_corr : bool, optional. Default True.
            If True, PSF correlation will be added
            as an extra parameter for density estimations.
            NB: the PSF fits image must be provided.

        do_local_var : bool, optional. Default is True.
            If True, adds local variance as an extra parameter,
            for density estimations. 
        
        do_nearsources: boolean. Default is False.
            If true it adds number of nearest neighnours as an extra
            parameter. It looks for sources around 5 beam sizes.

        psf_corr_region : int, optional. Default value is 5. 
            Data size to correlate around a source, in beam sizes.
 
        local_var_region: int, optional. Default 10.
            Data size to compute the local variance in beam sizes.

        rel_excl_src : floats, optional. Default is None. 
            Excludes sources in a specified region
            e.g ra, dec, radius in degrees. For
            2 regions: ra1, dec1, radius1: ra2, dec2, radius2, etc.

        pos_smooth : float, optional. Default 2.
            Masking threshold for the positive image.
            For default value 2, data peaks < 2 * image noise
            are masked.

        neg_smooth : float, optional. Default 2.
            Similar to pos_smooth but applied to the negative image.

        thresh_isl :  float, optional. Default is 3.
            Threshold for forming islands in the positive image

        thresh_pix : float, optional. Default is 5.
            Threshold for model fitting, in positive image.

        neg_thresh_isl : float, optional. Default is 3. 
            Simialr to thresh_isl but for negative image.

        neg_thresh_pix : float, optional. Default is 5. 
            Similar to thresh_pix but for negative image.

        savefits: boolean. Default is False.
            If True a negative image is saved.

        reset_rel: boolean. Default is False. If true then
            sources with correlation < 0.002 and rel >0.60
            have their reliabilities set to 0.

        increase_beam_cluster: boolean, optional. If True, sources
            groupings will be increase by 20% the beam size. If False,
            the actual beam size will be used. Default is False.

        savemask_pos: boolean, optional. If true the mask applied on 
            the positive side of an image after smoothing is saved.
            
        savemask_neg: Similar to savemask_pos but for the negative
            side of an image.
        
        loglevel : int, optional. Default is 0.
            Provides Pythonlogging options, 0, 1, 2 and 3 are for info, debug,
            error and critial respectively.
   
         kw : kward for source extractions. Should be a mapping e.g
            kw['thresh_isl'] = 2.0 or kw['do_polarization'] = True 
        """


       
        self.prefix = prefix

        # log level  
        self.loglevel = loglevel
        self.log = utils.logger(self.loglevel, prefix=self.prefix)

        
        # image, psf image
        self.imagename = imagename
        self.psfname = psfname 
      
        # reading imagename data
        imagedata, self.wcs, self.header, self.pixelsize =\
            utils.reshape_data(self.imagename, prefix=self.prefix)

        self.imagedata = numpy.array(imagedata, dtype=numpy.float32)
        self.image2by2 = numpy.array(utils.image_data(imagedata, prefix),
                             dtype=numpy.float32)

        self.bmaj = numpy.deg2rad(self.header["BMAJ"])

        # boolean optionals    
        self.makeplots = makeplots
        self.do_local_var = do_local_var
        self.nearsources = do_nearsources
        self.do_psf_corr = do_psf_corr
        self.savemaskpos = savemask_pos
        self.savemaskneg = savemask_neg
        self.savefits = savefits
        self.derel = reset_rel

        if not self.psfname:
            self.log.info(" No psf provided, do_psf_corr is set to False.")
            self.do_psf_corr = False

        if self.psfname:
            psfdata, self.psfhdr = utils.open_psf_image(self.psfname)
            self.psfdata = utils.image_data(psfdata, prefix)
 
        # computing negative noise
        self.noise, self.mean = utils.negative_noise(self.imagedata, self.prefix) #here is 2X2 data here
        
        self.log.info(" The negative noise is %e Jy/beam"%self.noise)
        if self.noise == 0: 
            self.log.debug(" The negative noise is 0, check image")

        # source finder initialization
        self.sourcefinder_name  = sourcefinder_name
        self.log.info(" Using %s source finder to extract the sources."%
                      self.sourcefinder_name)

        self.negimage = self.prefix + "_negative.fits"
        
        negativedata =  utils.invert_image(
                               self.imagename, self.imagedata,
                               self.header, self.negimage, prefix)
        self.negimage2by2 = numpy.array(utils.image_data(negativedata, prefix),
                             dtype=numpy.float32)
        self.negativedata = numpy.array(negativedata, numpy.float32)
       
        # smoothing factors
        self.pos_smooth = pos_smooth
        self.neg_smooth = neg_smooth
        
        # region to evaluate
        self.corrstep = psf_corr_region
        self.localstep = local_var_region
        self.radiusrm = rel_excl_src
        self.do_beam = increase_beam_cluster
         
        beam_pix = int(round(numpy.rad2deg(self.bmaj)/self.pixelsize))
        self.locstep = self.localstep * beam_pix
        self.cfstep = self.corrstep * beam_pix
        self.bmin, self.bpa =  self.header["BMIN"], self.header["BPA"]

        self.opts_pos = {}
        if self.do_beam:
            bmaj = self.header["BMAJ"]
            self.opts_pos["beam"] = (1.2*bmaj, 1.2*self.bmin, self.bpa)

        # Pybdsm or source finder fitting thresholds
        self.thresh_isl = thresh_isl
        self.thresh_pix = thresh_pix
        self.opts_pos = dict(thresh_pix=self.thresh_pix,
                             thresh_isl=self.thresh_isl)
        
        self.opts_pos.update(kw)
        self.opts_neg = {}
        self.neg_thresh_isl = neg_thresh_isl
        self.neg_thresh_pix = neg_thresh_pix
        self.opts_neg["thresh_isl"] = self.neg_thresh_isl
        self.opts_neg["thresh_pix"] = self.neg_thresh_pix
Esempio n. 4
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
Esempio n. 5
0
    def __init__(self,
                 imagename,
                 psfname,
                 pmodel,
                 nmodel,
                 local_step=10,
                 snr_thresh=40,
                 high_corr_thresh=0.5,
                 negdetec_region=10,
                 negatives_thresh=5,
                 phasecenter_excl_radius=None,
                 prefix=None,
                 loglevel=0):
        """ Determines sources that require direction-dependent (DD)
            calibration solutions.

        psfname: PSF fits data

        pmodel: Model of the positive image.

        nmodel: Model of the negative image
 
        header: The header of the input image

        snr_thresh: float, optional. Default is 40.
             Any source with 40 x the minimum SNR.

        high_corr_thresh:  float, optional. Default is 0.5.
             Sources of high PSF correlation have correlation above 0.5.

        negdetec_region:  float, optional. Default is 10.
             Region to lookup for negative detections around. In beam size.

        negative_thresh:  float, optional. Default is 5.
             The number of nearby negative detections. Sources
             with number > 5 require direction
             dependent (DD) calibration solutions.

        phasecenter_excl_region:  float (in degrees), optional.
             A radius from the phase center (in beam sizes) to exclude the sources
             from the evaluation.

        prefix: str, optional. Sets a prefix to the output directory.

        loglevel: int, optional. Default 0. Python logging.
                  0, 1, 2, 3 for info, debug, error and 
                  critical, respectively.
        """

        self.loglevel = loglevel
        self.prefix = prefix
        self.log = utils.logger(self.loglevel, prefix=self.prefix)
        #image and psf image

        self.pmodel = pmodel
        self.nmodel = nmodel
        self.psfname = psfname

        self.log.info(" Loading image data")

        # tags
        self.dd_tag = "dE"

        # thresholds
        self.snr_factor = snr_thresh
        #self.localthresh = local_thresh
        self.corrthresh = high_corr_thresh
        self.negthresh = negatives_thresh

        with pyfits.open(imagename) as hdu:
            self.hdr = hdu[0].header
            self.data = utils.image_data(hdu[0].data)

        self.wcs = WCS(self.hdr, mode="pyfits")

        self.locstep = local_step

        #regions
        self.phaserad = phasecenter_excl_radius  # radius from the phase center
        self.negregion = negdetec_region  # region to look for negatives

        # conversion
        self.bmaj = self.hdr["BMAJ"]  # in degrees

        self.ra0 = numpy.deg2rad(self.hdr["CRVAL1"])
        self.dec0 = numpy.deg2rad(self.hdr["CRVAL2"])