Esempio n. 1
0
def new_plots(pos, data, layer=None, plot_type='blazar', vmax=1, levels=[]):
    ax0 = plt.subplot(1, 2, pos)
    ax0.get_xaxis().set_ticks([])
    ax0.get_yaxis().set_ticks([])
    image_size = 60 * 2  # image is 2 * 2 arcminutes
    len_x, len_y = data.shape
    x0, x1 = len_x * (0.65 + 0.125), len_x * 0.9
    y = len_y * 0.1
    plt.text((x0 + x1) / 2,
             y * (0.7),
             str(int(image_size * 0.25 * 0.5)) + '"',
             horizontalalignment='center',
             verticalalignment='center',
             fontsize=15,
             color='w')
    plt.plot([x0, x1], [y, y], 'w-', lw=1.5)

    image = ax0.imshow(data,
                       origin='lower',
                       cmap='viridis',
                       vmax=vmax,
                       vmin=0,
                       norm=DS9Normalize(stretch='arcsinh'))
    circle1 = plt.Circle([8, 8], (x1 - x0) * (6 / 15) / 2,
                         ls='--',
                         fc='None',
                         ec='w')
    ax0.add_artist(circle1)
    divider = make_axes_locatable(ax0)
    cax0 = divider.append_axes('bottom', size='5%', pad=0.05)
    cbar = plt.colorbar(image, cax=cax0, orientation='horizontal')
    cbar.ax.tick_params(labelsize=15)
    cbar.ax.set_xlabel(r'Jy beam$^{-1}$', fontsize=15)
    if plot_type is 'blazar':
        ax0.contour(data,
                    levels=levels,
                    origin='lower',
                    colors='white',
                    alpha=0.67)
    elif plot_type is 'diffuse':
        ax0.contour(layer,
                    levels=levels,
                    origin='lower',
                    colors='white',
                    alpha=0.67)
        ax0.contour(data, levels=levels, origin='lower', colors='magenta'
                    )  # in this case, data is the core subtracted array
Esempio n. 2
0
            x1s.append(x1)
            x2s.append(x2)
            y1s.append(y1)
            y2s.append(y2)

    distances = np.array(distances)
    my_max = np.max(distances)
    max_x1 = x1s[distances.argmax()]
    max_x2 = x2s[distances.argmax()]
    max_y1 = y1s[distances.argmax()]
    max_y2 = y2s[distances.argmax()]
    asec_max = my_max * 1.5  # 1.5" per pixel
    centre = ((max_y1 + max_y2) / 2, (max_x1 + max_x2) / 2)

    fig = plt.imshow(d, vmin=0, vmax=np.nanmax(d), origin='lower',
                     norm=DS9Normalize(stretch='arcsinh'))
    plt.colorbar()
    fig.axes.get_xaxis().set_visible(False)
    fig.axes.get_yaxis().set_visible(False)
    circle = plt.Circle(centre, my_max / 2, color='r', fill=False, alpha=0.5,
                        lw=2)
    fig = plt.gcf()
    ax = fig.gca()
    ax.add_artist(circle)

    plt.plot([max_y1, max_y2], [max_x1, max_x2], color='red', alpha=0.5, lw=2)
    plt.plot([(max_y1 + max_y2) / 2], [(max_x1 + max_x2) / 2], marker='o',
             color='red', alpha=0.5)
    plt.title(f'{source_name}\n5\u03C3 = {threshold * 1000:.3f} mJy; d = ' +
              f'{asec_max:.1f}"')
    # plt.show()
Esempio n. 3
0
def optical(sigma=4, my_directory='/data5/sean/ldr2'):
    """Plot Pan-STARRS data.

    Parameters
    ----------
    sigma : float or int
        The threshold of the significance to set the mask, as a factor of the
        local RMS. The default is 4.
    my_directory : string
        Working directory.
    """
    df = pd.read_csv(f'{my_directory}/catalogues/final.csv')

    plt.figure(figsize=(13.92, 8.60)).patch.set_facecolor('white')
    plt.rcParams['font.family'] = 'serif'
    plt.rcParams['mathtext.fontset'] = 'dejavuserif'
    mpl.rcParams['xtick.major.size'] = 10
    mpl.rcParams['xtick.major.width'] = 2
    mpl.rcParams['xtick.minor.size'] = 5
    mpl.rcParams['xtick.minor.width'] = 2
    mpl.rcParams['ytick.major.size'] = 10
    mpl.rcParams['ytick.major.width'] = 2
    mpl.rcParams['ytick.minor.size'] = 5
    mpl.rcParams['ytick.minor.width'] = 2
    mpl.rcParams['axes.linewidth'] = 2
    colors = ['#118ab2', '#06d6a0', '#ffd166', '#ef476f']
    sbar_asec = 30  # desired length of scalebar in arcseconds
    pix = 0.25  # arcseconds per pixel

    for source_name, ra, dec, mosaic, rms, z, pf in zip(df['Name'],
                                                        df['BZCAT RA'],
                                                        df['BZCAT Dec'],
                                                        df['Mosaic_ID'],
                                                        df['Isl_rms'],
                                                        df['redshift'],
                                                        df['Peak_flux']):
        source_name = '5BZB' + source_name
        sky_position = SkyCoord(ra, dec, unit='deg')
        if source_name == '5BZBJ1202+4444' or source_name == '5BZBJ1325+4115':
            size = [3, 3] * u.arcmin
            p = 54
        elif (source_name == '5BZBJ1419+5423' or
              source_name == '5BZBJ0945+5757'):
            size = [4, 4] * u.arcmin
            p = 72
        else:
            size = [2, 2] * u.arcmin
            p = 36
        print(source_name)
        p_hdu = fits.open(f'{my_directory}/panstarrs/{source_name}.i.'
                          'fits')[0]
        p_wcs = WCS(p_hdu.header)
        p_cutout = Cutout2D(p_hdu.data, sky_position, size=size, wcs=p_wcs)

        l_hdu = fits.open(f'{my_directory}/mosaics/{mosaic}-mosaic.fits')[0]
        l_wcs = WCS(l_hdu.header, naxis=2)
        l_cutout = Cutout2D(np.squeeze(l_hdu.data), sky_position, size=size,
                            wcs=l_wcs)

        if 4 * rms < (pf / 50):
            # see 2.2 of https://arxiv.org/pdf/1907.03726.pdf
            levels = [level * (pf / 50) / 1000 for level in [1, 2, 4, 8]]
        else:
            levels = [level * rms / 1000 for level in [4, 8, 16, 32]]

        ax = plt.subplot(projection=p_cutout.wcs)
        im = ax.imshow(p_cutout.data, vmin=0, vmax=8000, cmap='cubehelix_r',
                       origin='lower', norm=DS9Normalize(stretch='arcsinh'),
                       interpolation='gaussian')

        cbar = plt.colorbar(im)
        cbar.set_label('Excess counts', size=20)
        cbar.ax.tick_params(labelsize=20)

        ax.contour(l_cutout.data, transform=ax.get_transform(l_cutout.wcs),
                   levels=levels, origin='lower', colors=colors)

        plt.xlabel('Right ascension', fontsize=20, color='black')
        plt.ylabel('Declination', fontsize=20, color='black')
        ax.tick_params(axis='both', which='major', labelsize=20)
        plt.minorticks_on()
        ax.tick_params(which='minor', length=0)

        kpc_per_asec = get_kpc_per_asec(z=z)
        sbar = sbar_asec / pix  # length of scalebar in pixels
        kpc_per_pixel = kpc_per_asec * pix
        s = p_cutout.data.shape[1]  # plot scalebar
        plt.plot([p, p + sbar], [s - p, s - p], marker='None', lw=2, color='b')
        plt.text(p,  s - p + 10 * (p / 36), f'{sbar_asec:.0f}" = '
                 f'{kpc_per_pixel * sbar:.0f} kpc', fontsize=20, color='b')

        plt.savefig(f'{my_directory}/images/panstarrs-{source_name}.png')
        plt.clf()
Esempio n. 4
0
    def __init__(self,filelist,
                 step=1.0,outdir='./nudged/',ext='',clobber=False):
        self.filelist = filelist
        # datalist holds current state of arrays
        self.datalist = map(pyfits.getdata,filelist)
        self.step = step
        self.outdir = outdir
        self.ext = ext
        self.clobber = clobber
        self.current = 0
        self.orig_data = pyfits.getdata(filelist[0])
        self.active_data = self.datalist[0]
        # store total offsets
        self.offsets = np.zeros((len(filelist),2))

        # initialize norm
        self.norm = DS9Normalize(stretch='linear')
        

        # set up subparser
        self.subparser=argparse.ArgumentParser(description='Parse window text.',prog='')
        self.subparser.add_argument('-s',type=float,help='Step size (default=%.1f)' % self.step)
        self.subparser.add_argument('--stretch',choices=['linear','sqrt','arcsinh','log','power','squared'],help='Choose image stretch (default = stretch)')
        self.subparser.add_argument('--clip_lo',type=float,help='Clip minimum intensity percentile')
        self.subparser.add_argument('--clip_hi',type=float,help='Clip maximum intensity percentile')
        self.subparser.add_argument('-w',action='store_true',help="Write current frame to output directory (outdir=%s)"%self.outdir)
        self.subparser.add_argument('-wa',action='store_true',help="Write all frames to output directory (outdir=%s)"%self.outdir)
        self.subparser.add_argument('-wq',action='store_true',help="Write all frames to output directory and quit (outdir=%s)"%self.outdir)
        self.subparser.add_argument('-r',action='store_true',help='Restore original')
        self.subparser.add_argument('--c',action='store_true',help='Force clobber status to True on write')

        self.subparser.add_argument('--q',action='store_true',help='Quit')
        self.fig = plt.figure()
        self.fig.canvas.mpl_disconnect(self.fig.canvas.manager.key_press_handler_id)
        self.keycid = self.fig.canvas.mpl_connect('key_press_event',self.onkey)

        self.fig.canvas.mpl_connect('button_press_event', self.onclick)
        self.fig.canvas.mpl_connect('button_release_event', self.onrelease)

        # Hold x,y drag coords
        self.dragfrom = None
        
        self.pausetext = '-'
        self.pid = None


        # Make directory if doesn't exist
        try:
            mkdir(self.outdir)
        except OSError:
            #directory exists. no big deal.
            pass
        
        print "Type directly into figure"
        print "'left/right/up/down' to translate image"
        print "'</>' to choose previous/next image in input list"
        print "'-h' to see additional options"
        print "'--q' to quit"
        print
        
        #Show initial
        self.display(self.active_data)
        self.displaytext('[0, 0], s=%.2f'%self.step,x=0.60)
        plt.show()
Esempio n. 5
0
    def parsetext(self,text):
        args = None
        try:
            # catch -h, or error exit
            args = self.subparser.parse_args(text.split())
        except SystemExit:
            return
            
        if not args:
            return

        if args.c:
            self.clobber = True
            print 'Force clobber on write'
            
        if args.s:
            self.step = args.s
            print 'Step size changed to %.2f' % self.step

        if args.stretch:
            print 'Changed stretch to %s' % args.stretch
            self.norm.stretch = args.stretch
            self.display(self.active_data)

        if args.clip_lo:
            print 'Clip lo changed to %.2f' % args.clip_lo
            self.norm.clip_lo = args.clip_lo
            self.display(self.active_data)

        if args.clip_hi:
            print 'Clip hi changed to %.2f' % args.clip_hi
            self.norm.clip_hi = args.clip_hi
            self.display(self.active_data)

            
        if args.r:
            self.active_data = self.orig_data.copy()
            self.offsets[self.current][0] = 0.0
            self.offsets[self.current][1] = 0.0
            self.norm = DS9Normalize(stretch='linear')
            self.display(self.active_data)
            print 'Restored image from %s' % self.filelist[self.current]

        if args.w:
            h = pyfits.getheader(self.filelist[self.current])
            h['N_ORIG_F'] = (self.filelist[self.current],'Original file before nudge')
            h['N_XS'] = (self.offsets[self.current][0],'Xshift of nudge')
            h['N_YS'] = (self.offsets[self.current][1],'Yshift of nudge')
            outfile = os.path.basename(self.filelist[self.current])
            outfile = os.path.splitext(outfile)
            outfile = ''.join([outfile[0],self.ext,outfile[1]])
            outfile = os.path.join(self.outdir,outfile)
            try:
                pyfits.writeto(outfile,data=self.active_data,header=h,clobber=self.clobber)
            except IOError as e:
                print e, "'--c' to force overwrite"
            else:
                print '%s: written to disk, s = [%.2f, %.2f]' % (outfile,self.offsets[self.current][0],self.offsets[self.current][1])

        if args.wq:
            args.wa = True
            args.q = True
                
        if args.wa:
            for idx in range(0,len(self.filelist)):
                h = pyfits.getheader(self.filelist[idx])
                h['N_ORIG_F'] = (self.filelist[idx],'Original file before nudge')
                h['N_XS'] = (self.offsets[idx][0],'Xshift of nudge')
                h['N_YS'] = (self.offsets[idx][1],'Yshift of nudge')
                outfile = os.path.basename(self.filelist[idx])
                outfile = os.path.splitext(outfile)
                outfile = ''.join([outfile[0],self.ext,outfile[1]])
                outfile = os.path.join(self.outdir,outfile)
                try:
                    if idx == self.current:
                        pyfits.writeto(outfile,data=self.active_data,header=h,clobber=self.clobber)
                    else:
                        pyfits.writeto(outfile,data=self.datalist[idx],header=h,clobber=self.clobber)
                except IOError as e:
                    print e, "'--c' to force overwrite"
                    args.q = False #don't quit if file fails to write
                else:
                    print '%s: written to disk, s = [%.2f, %.2f]' % (outfile,self.offsets[idx][0],self.offsets[idx][1])

        if args.q:
            plt.close()
            exit()
Esempio n. 6
0
def loop_through_sources(sigma=4, my_directory='/data5/sean/ldr2'):
    """Plot postage stamp images of LDR2 BL Lacs.

    Parameters
    ----------
    sigma : float or integer
        The threshold of the significance to set the mask, as a factor of the
        local RMS. The default is 4.
    my_directory : string
        Working directory.

    Returns
    -------
    string
        The name of the CSV containing the results.
    """
    df = pd.read_csv(f'{my_directory}/catalogues/pulsars-10asec-match.csv')

    plt.figure(figsize=(13.92, 8.60)).patch.set_facecolor('white')
    plt.rcParams['font.family'] = 'serif'
    plt.rcParams['mathtext.fontset'] = 'dejavuserif'
    mpl.rcParams['xtick.major.size'] = 10
    mpl.rcParams['xtick.major.width'] = 2
    mpl.rcParams['xtick.minor.size'] = 5
    mpl.rcParams['xtick.minor.width'] = 2
    mpl.rcParams['ytick.major.size'] = 10
    mpl.rcParams['ytick.major.width'] = 2
    mpl.rcParams['ytick.minor.size'] = 5
    mpl.rcParams['ytick.minor.width'] = 2
    mpl.rcParams['axes.linewidth'] = 2
    dummy = 123456
    sbar_asec = 30  # desired length of scalebar in arcseconds
    pix = 1.5  # arcseconds per pixel

    for source_name, ra, dec, mosaic, rms in zip(df['NAME'], df['RAJD'],
                                                 df['DECJD'], df['Mosaic_ID'],
                                                 df['Isl_rms']):

        threshold = sigma * rms / 1000  # jansky
        hdu = fits.open(f'{my_directory}/mosaics/{mosaic}-mosaic.fits')[0]
        wcs = WCS(hdu.header, naxis=2)
        sky_position = SkyCoord(ra, dec, unit='deg')
        size = [2, 2] * u.arcmin
        p = 6

        cutout = Cutout2D(np.squeeze(hdu.data),
                          sky_position,
                          size=size,
                          wcs=wcs)
        d = cutout.data
        copy_d = np.copy(d)
        another_copy_d = np.copy(d)
        d[d < threshold] = 0
        d[d >= threshold] = 1
        rows, cols = d.shape

        d = label(d)  # label islands of emission
        source_islands = nearest_to_centre(d, percent=0.1)
        for source_island in source_islands:
            d[d == source_island] = dummy

        d[d != dummy] = 0
        copy_d[d != dummy] = 0
        set_to_nil = []  # identify values we can set to zero for being inside
        for r in range(rows):  # set to 0 if surrounded by non nans
            for c in range(cols):
                try:
                    if (d[r - 1, c - 1] != 0 and d[r - 1, c] != 0
                            and d[r - 1, c + 1] != 0 and d[r, c - 1] != 0
                            and d[r, c + 1] != 0 and d[r + 1, c - 1] != 0
                            and d[r + 1, c] != 0 and d[r + 1, c + 1] != 0):
                        set_to_nil.append((r, c))
                except IndexError:
                    print(f'Index error for {source_name}.')
                    continue

        for r, c in set_to_nil:
            d[r, c] = 0  # needs separate loop to avoid checkered pattern

        # d is an outline of the source (one) and everything else is zero
        # copy_d is the source with flux values and everything else is zero
        # another_copy_d has flux values throughout
        good_cells = []
        for r in range(rows):
            for c in range(cols):
                if d[r, c] != 0:
                    good_cells.append([r, c])

        x, y, r = smallestenclosingcircle.make_circle(good_cells)

        ax = plt.subplot(projection=cutout.wcs)
        plt.xlabel('Right ascension', fontsize=20, color='black')
        plt.ylabel('Declination', fontsize=20, color='black')
        ax.tick_params(axis='both', which='major', labelsize=20)
        plt.imshow(another_copy_d,
                   vmin=0,
                   vmax=np.nanmax(another_copy_d),
                   origin='lower',
                   norm=DS9Normalize(stretch='arcsinh'),
                   cmap='plasma_r')  # interpolation='gaussian'
        beam = Circle((6, 6),
                      radius=2,
                      linestyle='dashed',
                      lw=2,
                      fc='none',
                      edgecolor='blue')
        diffuse = Circle((y + 0.5, x + 0.5),
                         radius=r,
                         fc='none',
                         edgecolor='k',
                         lw=2)
        ax.add_patch(beam)
        ax.add_patch(diffuse)

        sbar = sbar_asec / pix  # length of scalebar in pixels
        s = cutout.data.shape[1]  # plot scalebar
        plt.plot([p, p + sbar], [s - p, s - p], marker='None', lw=2, color='b')
        plt.text(p,
                 s - (5 * p / 6),
                 f'{sbar_asec:.0f}"',
                 fontsize=20,
                 color='b')

        cbar = plt.colorbar()
        cbar.set_label(r'Jy beam$^{-1}$', size=20)
        cbar.ax.tick_params(labelsize=20)
        plt.minorticks_on()
        plt.tick_params(which='minor', length=0)
        plt.contour(another_copy_d,
                    levels=[threshold],
                    origin='lower',
                    colors='w')
        plt.contour(another_copy_d - copy_d,
                    levels=[threshold],
                    colors='grey',
                    origin='lower')
        plt.savefig(f'{my_directory}/images/pulsar-{source_name}.png')
        plt.clf()

        print(f'{source_name}: {r * 1.5 * 2:.1f}"')
def measure_extent_radio_galaxies(my_dir='/data5/sean/deep-fields/catalogues/',
                                  nah=False):
    """Measure the size of radio galaxies.
    """

    results_csv = f'{my_dir}../results/extention-radio-galaxies.csv'
    if nah:
        return results_csv  # do not do anything

    df = pd.read_csv(f'{my_dir}radio.galaxies.ldr1.csv')  # load data
    fields = [f'/data1/lotss-data/{m}-mosaic.fits' for m in df['Mosaic_ID']]
    thresholds = 5 * df['Isl_rms'] / 1000  # converting to jansky
    plt.figure(figsize=(8, 8))

    result_header = ('Name,Class,LM flux (mJy),LM size ("),Width ("),Width' +
                     ' (kpc),5 * rms (mJy),Redshift,NAT,WAT,D-D\n')

    if not os.path.exists(results_csv):
        with open(results_csv, 'a') as f:
            f.write(result_header)

    # skipping these sources as they are too complicated
    skip_list = ['ILTJ105155.09+552329.0', 'ILTJ104703.03+523023.4']
    i = 0

    for (source_name, ra, dec, field, threshold, fri, frii, redshift, nat, wat,
         dd, lm_size, lm_flux) in zip(df['Source_Name_1'], df['RA_1'],
                                      df['DEC_1'], fields, thresholds,
                                      df['FR1'], df['FR2'], df['z_best'],
                                      df['NAT'], df['WAT'], df['D-D'],
                                      df['LM_dec_size'], df['LM_Flux']):

        save = f'{my_dir}../images/extention-radio-galaxies/{source_name}.png'
        if os.path.exists(save):
            print(f'{save} already exists so it is being skipped.')
            continue

        if source_name in skip_list:
            print(f'{source_name} is too complicated so it is being skipped.')
            continue

        # already removed small sources and ambiguous sources from the sample
        source_type = 'FR-I' if fri else 'FR-II'

        # if source_name != 'ILTJ130804.04+550835.4':  # for testing one source
        #     continue

        # try:
        hdu = fits.open(field)[0]
        # except FileNotFoundError:  # fits might have different name
        #     print(f'{field} does not exist.')
        #     continue

        wcs = WCS(hdu.header, naxis=2)
        sky_position = SkyCoord(ra, dec, unit='deg')
        s = math.ceil((lm_size * 2) / 60)
        # already have adhoc masks for P196+55 field at [3, 3] arcmin but for
        # the rest we take the size of the source from lomorph
        size = [3, 3] if field[-19:-5] == 'P196+55-mosaic' else [s, s]

        # some sources need a bigger cutout
        if source_name == 'ILTJ130140.02+540825.9':
            size = [4, 4]
        elif source_name == 'ILTJ130331.30+540024.1':
            size = [6, 6]

        cutout = Cutout2D(np.squeeze(hdu.data),
                          sky_position,
                          size=size * u.arcmin,
                          wcs=wcs)

        d = cutout.data
        d[d < threshold] = np.nan
        d = manual_mask(name=source_name, data=d)
        rows, cols = d.shape
        good_cells = []

        for r in range(rows):
            for c in range(cols):
                if not np.isnan(d[r, c]):
                    good_cells.append([r, c])

        # find distance between good_cell and all other good_cells
        distances, x1s, x2s, y1s, y2s = [], [], [], [], []
        for (x1, y1) in good_cells:
            for (x2, y2) in good_cells:
                distances.append(np.sqrt((x1 - x2)**2 + (y1 - y2)**2))
                x1s.append(x1)
                x2s.append(x2)
                y1s.append(y1)
                y2s.append(y2)

        distances = np.array(distances)
        # try:
        #     my_max = np.max(distances)
        # except ValueError:
        #     print(f'Failed for {source_name}.')
        #     continue

        max_x1 = x1s[distances.argmax()]
        max_x2 = x2s[distances.argmax()]
        max_y1 = y1s[distances.argmax()]
        max_y2 = y2s[distances.argmax()]
        # asec_max = my_max * 1.5  # 1.5" per pixel

        # this removes highly curved sources
        # if lm_size / asec_max > 1.75 or asec_max / lm_size > 1.75:
        #     print(f'{source_name} is too curved so it is being skipped.')
        #     continue

        # for good cells find the distance from it to the point on the line, we
        # assume we look down the longest line and the source is flat in the
        # plane of the sky (https://stackoverflow.com/a/52756183/6386612)
        p1 = np.array([max_x1, max_y1])
        p2 = np.array([max_x2, max_y2])
        widths = []
        width_x, width_y = [], []

        for (x, y) in good_cells:
            p3 = np.array([x, y])
            widths.append(np.cross(p2 - p1, p3 - p1) / np.linalg.norm(p2 - p1))
            width_x.append(x)
            width_y.append(y)

        widths = np.array(widths)
        my_max_width = np.max(widths)
        my_min_width = np.min(widths)
        width_x_max = width_x[widths.argmax()]
        width_y_max = width_y[widths.argmax()]
        width_x_min = width_x[widths.argmin()]
        width_y_min = width_y[widths.argmin()]
        asec_width = (my_max_width + np.abs(my_min_width)) * 1.5  # 1.5"/pixel

        plt.imshow(d,
                   vmin=0,
                   vmax=np.nanmax(d),
                   origin='lower',
                   norm=DS9Normalize(stretch='arcsinh'))

        plt.colorbar()
        plt.plot([max_y1, max_y2], [max_x1, max_x2],
                 color='red',
                 alpha=0.5,
                 lw=2)
        plt.plot([width_y_max], [width_x_max],
                 marker='o',
                 markersize=10,
                 color='red',
                 alpha=0.5)
        plt.plot([width_y_min], [width_x_min],
                 marker='o',
                 markersize=10,
                 color='red',
                 alpha=0.5)

        plt.minorticks_on()
        plt.grid(which="both", linewidth=0.72, color="k")
        plt.tick_params(which="minor", length=0)

        my_string = ''
        if nat:
            my_string += 'NAT '
        elif wat:
            my_string += 'WAT '
        if dd:
            my_string += 'D-D '

        plt.title(f'{source_name}\n{source_type}; {my_string}5\u03C3 = ' +
                  f'{threshold * 1000:.3f} mJy; width = {asec_width:.1f}"')
        # plt.show()
        plt.savefig(save)
        plt.clf()

        _, kpc = get_dl_and_kpc_per_asec(z=redshift)
        kpc_width = kpc * asec_width

        results = (f'{source_name},{source_type},{lm_flux},{lm_size},' +
                   f'{asec_width},{kpc_width},{threshold * 1000},{redshift},' +
                   f'{nat},{wat},{dd}\n')

        with open(results_csv, 'a') as f:
            f.write(results)

        # build clean sample on visual inspection
        i += 1
        if i > 100:
            return
def ghz(sigma=4, my_directory='/data5/sean/ldr2'):
    """Plot FIRST data.

    Parameters
    ----------
    sigma : float or int
        The threshold of the significance to set the mask, as a factor of the
        local RMS. The default is 4.
    my_directory : string
        Working directory.
    """
    df = pd.read_csv(f'{my_directory}/catalogues/final.csv')

    plt.figure(figsize=(13.92, 8.60)).patch.set_facecolor('white')
    plt.rcParams['font.family'] = 'serif'
    plt.rcParams['mathtext.fontset'] = 'dejavuserif'
    mpl.rcParams['xtick.major.size'] = 10
    mpl.rcParams['xtick.major.width'] = 2
    mpl.rcParams['xtick.minor.size'] = 5
    mpl.rcParams['xtick.minor.width'] = 2
    mpl.rcParams['ytick.major.size'] = 10
    mpl.rcParams['ytick.major.width'] = 2
    mpl.rcParams['ytick.minor.size'] = 5
    mpl.rcParams['ytick.minor.width'] = 2
    mpl.rcParams['axes.linewidth'] = 2
    colors = ['#118ab2', '#06d6a0', '#ffd166', '#ef476f']
    sbar_asec = 30  # desired length of scalebar in arcseconds
    pix = 1.8  # arcseconds per pixel

    for source_name, ra, dec, mosaic, rms, z, f_rms, pf in zip(
            df['Name'], df['BZCAT RA'], df['BZCAT Dec'], df['Mosaic_ID'],
            df['Isl_rms'], df['redshift'], df['RMS'], df['Peak_flux']):
        source_name = '5BZB' + source_name
        sky_position = SkyCoord(ra, dec, unit='deg')
        if source_name == '5BZBJ1202+4444' or source_name == '5BZBJ1325+4115':
            size = [3, 3] * u.arcmin
            x = 9 * (1.5 / pix)  # to get the scalebar in the same place
        elif (source_name == '5BZBJ1419+5423'
              or source_name == '5BZBJ0945+5757'):
            size = [4, 4] * u.arcmin
            x = 12 * (1.5 / pix)
        else:
            size = [2, 2] * u.arcmin
            x = 6 * (1.5 / pix)

        f_hdu = fits.open(f'{my_directory}/first/{source_name}.fits')[0]
        f_wcs = WCS(f_hdu.header, naxis=2)
        print(f'{source_name}')
        f_cutout = Cutout2D(np.squeeze(f_hdu.data),
                            sky_position,
                            size=size,
                            wcs=f_wcs)

        l_hdu = fits.open(f'{my_directory}/mosaics/{mosaic}-mosaic.fits')[0]
        l_wcs = WCS(l_hdu.header, naxis=2)
        l_cutout = Cutout2D(np.squeeze(l_hdu.data),
                            sky_position,
                            size=size,
                            wcs=l_wcs)

        if 4 * rms < (pf / 50):
            # see 2.2 of https://arxiv.org/pdf/1907.03726.pdf
            levels = [level * (pf / 50) / 1000 for level in [1, 2, 4, 8]]
        else:
            levels = [level * rms / 1000 for level in [4, 8, 16, 32]]
        f_level = f_rms * 4 / 1000

        ax = plt.subplot(projection=f_cutout.wcs)
        im = ax.imshow(f_cutout.data,
                       vmin=0,
                       vmax=np.max(f_cutout.data),
                       cmap='cubehelix_r',
                       origin='lower',
                       interpolation='gaussian',
                       norm=DS9Normalize(stretch='arcsinh'))
        ax.contour(f_cutout.data,
                   levels=[f_level],
                   origin='lower',
                   colors=['k'])

        cbar = plt.colorbar(im)
        cbar.set_label(r'Jy beam$^{-1}$', size=20)
        cbar.ax.tick_params(labelsize=20)

        ax.contour(l_cutout.data,
                   transform=ax.get_transform(l_cutout.wcs),
                   levels=levels,
                   origin='lower',
                   colors=colors)

        beam = Circle((6, 6),
                      radius=1.5,
                      linestyle='dashed',
                      lw=2,
                      fc='none',
                      edgecolor='blue')  # beam = 5.4" diameter, 1 pixel = 1.8"
        ax.add_patch(beam)

        plt.xlabel('Right ascension', fontsize=20, color='black')
        plt.ylabel('Declination', fontsize=20, color='black')
        ax.tick_params(axis='both', which='major', labelsize=20)
        plt.minorticks_on()
        ax.tick_params(which='minor', length=0)
        plt.xlim(0, f_cutout.data.shape[0])
        plt.ylim(0, f_cutout.data.shape[1])

        kpc_per_asec = get_kpc_per_asec(z=z)
        sbar = sbar_asec / pix  # length of scalebar in pixels
        kpc_per_pixel = kpc_per_asec * pix
        s = f_cutout.data.shape[1]
        plt.plot([x, x + sbar], [s - x, s - x], marker='None', lw=2, color='b')
        plt.text(x,
                 s - (4.167 * x / 5), f'{sbar_asec:.0f}" = '
                 f'{kpc_per_pixel * sbar:.0f} kpc',
                 fontsize=20,
                 color='b')

        plt.savefig(f'{my_directory}/images/first-{source_name}.png')
        plt.clf()
Esempio n. 9
0
def loop_through_sources(sigma=5, my_directory='/data5/sean/ldr2'):
    """Plot postage stamp images of LDR2 BL Lacs.

    Parameters
    ----------
    sigma : float or integer
        The threshold of the significance to set the mask, as a factor of the
        local RMS. The default is 5.
    my_directory : string
        Working directory.

    Returns
    -------
    string
        The name of the CSV containing the results.
    """
    results_path = f'{my_directory}/measure_point_sources/'
    if Path(results_path).exists() and Path(results_path).is_dir():
        shutil.rmtree(results_path)
    os.mkdir(results_path, 0o755)
    results_csv = (f'{results_path}/measure_point_sources.csv')
    result_header = ('BZB,Name,RA,Dec,S_peak (mJy),RMS (mJy/beam),D (asec)')
    print(result_header)
    with open(results_csv, 'a') as f:
        f.write(f'{result_header}\n')

    df = pd.read_csv(f'{my_directory}/S_Code=S,DC_Maj=0,_1deg - S_Code=S,'
                     'DC_Maj=0,_1deg.csv')
    df = df[(df['PS SNR'] > 10) & (df['Degree separation'] < 0.5)]
    df = df[(df['DC_Maj'] == 0) & (df['DC_Min'] == 0) & (df['S_Code'] == 'S')]

    plt.figure(figsize=(13.92, 8.60)).patch.set_facecolor('white')
    plt.rcParams['font.family'] = 'serif'
    plt.rcParams['mathtext.fontset'] = 'dejavuserif'
    mpl.rcParams['xtick.major.size'] = 10
    mpl.rcParams['xtick.major.width'] = 2
    mpl.rcParams['xtick.minor.size'] = 5
    mpl.rcParams['xtick.minor.width'] = 2
    mpl.rcParams['ytick.major.size'] = 10
    mpl.rcParams['ytick.major.width'] = 2
    mpl.rcParams['ytick.minor.size'] = 5
    mpl.rcParams['ytick.minor.width'] = 2
    mpl.rcParams['axes.linewidth'] = 2
    dummy = 123456
    pix = 1.5  # arcseconds per pixel
    colors = ['#118ab2', '#06d6a0', '#ffd166', '#ef476f']
    for bzb, bzb_mosaic, source_name, ra, dec, mosaic, rms, pf in zip(
        df['BZB name'], df['BZB mosaic'], df['Source_Name'], df['RA'],
            df['DEC'], df['Mosaic_ID'], df['Isl_rms'], df['Peak_flux']):
        if not bzb_mosaic:
            continue  # don't use the source if it is from a different pointing
        threshold = sigma * rms / 1000   # jansky
        hdu = fits.open(f'{my_directory}/mosaics/{mosaic}-mosaic.fits')[0]
        wcs = WCS(hdu.header, naxis=2)
        sky_position = SkyCoord(ra, dec, unit='deg')
        size = [1, 1] * u.arcmin
        cutout = Cutout2D(np.squeeze(hdu.data), sky_position, size=size,
                          wcs=wcs)
        d = cutout.data
        copy_d = np.copy(d)
        last_copy = np.copy(d)
        another_copy_d = np.copy(d)
        d[d < threshold] = 0
        d[d >= threshold] = 1
        rows, cols = d.shape

        d = label(d)
        source_islands = nearest_to_centre(d, percent=0.1)
        for source_island in source_islands:
            d[d == source_island] = dummy
        d[d != dummy] = 0
        copy_d[d != dummy] = 0
        set_to_nil = []  # identify values we can set to zero for being inside
        for r in range(rows):  # set to 0 if surrounded by non nans
            for c in range(cols):
                try:
                    if (d[r - 1, c - 1] != 0 and d[r - 1, c] != 0 and
                        d[r - 1, c + 1] != 0 and d[r, c - 1] != 0 and
                        d[r, c + 1] != 0 and d[r + 1, c - 1] != 0 and
                            d[r + 1, c] != 0 and d[r + 1, c + 1] != 0):
                        set_to_nil.append((r, c))
                except IndexError:
                    print(f'Index error for {source_name}.')
                    continue

        for r, c in set_to_nil:
            d[r, c] = 0  # needs separate loop to avoid checkered pattern

        # d is an outline of the source (one) and everything else is zero
        # copy_d is the source with flux values and everything else is zero
        # another_copy_d has flux values throughout
        good_cells = []
        for r in range(rows):
            for c in range(cols):
                if d[r, c] != 0:
                    good_cells.append([r, c])

        x, y, r = smallestenclosingcircle.make_circle(good_cells)

        ax = plt.subplot(projection=cutout.wcs)
        plt.xlabel('Right ascension', fontsize=20, color='black')
        plt.ylabel('Declination', fontsize=20, color='black')
        ax.tick_params(axis='both', which='major', labelsize=20)
        plt.imshow(another_copy_d, vmin=0, vmax=np.nanmax(another_copy_d),
                   origin='lower', norm=DS9Normalize(stretch='arcsinh'),
                   cmap='cubehelix_r', interpolation='gaussian')
        beam = Circle((6, 6), radius=2, linestyle='dashed', lw=2, fc='none',
                      edgecolor='blue')  # radius=2 pixels -> 3" -> diameter=6"
        diffuse = Circle((y + 0.5, x + 0.5), radius=r, fc='none',
                         edgecolor='k', lw=2)
        ax.add_patch(beam)
        ax.add_patch(diffuse)
        cbar = plt.colorbar()
        cbar.set_label(r'Jy beam$^{-1}$', size=20)
        cbar.ax.tick_params(labelsize=20)
        plt.minorticks_on()
        plt.tick_params(which='minor', length=0)
        levels = [level * threshold for level in [1, 2, 4, 8]]
        plt.contour(another_copy_d, levels=levels, origin='lower',
                    colors=colors)
        plt.contour(last_copy, levels=[-threshold * (3 / 5)], colors='grey',
                    origin='lower', linestyles='dashed')
        saved = f'{results_path}/{source_name}.png'
        plt.savefig(saved)
        plt.clf()
        # os.system(f'convert {saved} -trim {saved}')  # removes whitespace
        result = (f'{bzb},{source_name},{ra},{dec},{pf},{rms},'
                  f'{r * pix * 2:.1f}')
        print(result)
        with open(results_csv, 'a') as f:
            f.write(f'{result}\n')
    return results_csv
Esempio n. 10
0
def loop_through_sources(sigma=5, my_directory='/data5/sean/ldr2'):
    """Plot postage stamp images of LDR2 BL Lacs.

    Parameters
    ----------
    sigma : float or integer
        The threshold of the significance to set the mask, as a factor of the
        local RMS. The default is 4.
    my_directory : string
        Working directory.

    Returns
    -------
    string
        The name of the CSV containing the results.
    """
    results_csv = f'{my_directory}/images/ldr2.csv'
    try:
        os.remove(results_csv)
    except OSError:
        pass
    df = pd.read_csv(f'{my_directory}/catalogues/final.csv')
    result_header = ('Name,RA,Dec,RMS (uJy),Redshift,Width ("),Width (kpc),'
                     'Peak flux (mJy)\n')

    with open(results_csv, 'a') as f:
        f.write(result_header)

    plt.figure(figsize=(13.92, 8.60)).patch.set_facecolor('white')
    plt.rcParams['font.family'] = 'serif'
    plt.rcParams['mathtext.fontset'] = 'dejavuserif'
    mpl.rcParams['xtick.major.size'] = 10
    mpl.rcParams['xtick.major.width'] = 2
    mpl.rcParams['xtick.minor.size'] = 5
    mpl.rcParams['xtick.minor.width'] = 2
    mpl.rcParams['ytick.major.size'] = 10
    mpl.rcParams['ytick.major.width'] = 2
    mpl.rcParams['ytick.minor.size'] = 5
    mpl.rcParams['ytick.minor.width'] = 2
    mpl.rcParams['axes.linewidth'] = 2
    dummy = 123456
    sbar_asec = 30  # desired length of scalebar in arcseconds
    pix = 1.5  # arcseconds per pixel
    colors = ['#118ab2', '#06d6a0', '#ffd166', '#ef476f']
    print('Name, asec, kpc, threshold, UL?')
    for source_name, ra, dec, mosaic, rms, z, pf, comp in zip(
            df['Name'], df['BZCAT RA'], df['BZCAT Dec'], df['Mosaic_ID'],
            df['Isl_rms'], df['redshift'], df['Peak_flux'], df['Compact']):
        source_name = '5BZB' + source_name
        source_name = source_name.replace(' ', '')
        threshold = sigma * rms / 1000  # jansky
        thresh_ans = f'{sigma}sigma'
        # if threshold < (pf / 50) / 1000:
        #     # see 2.2 of https://arxiv.org/pdf/1907.03726.pdf
        #     four_sigma = threshold
        #     threshold = (pf / 50) / 1000
        #     thresh_ans = '1/50 S_peak'
        hdu = fits.open(f'{my_directory}/mosaics/{mosaic}-mosaic.fits')[0]
        wcs = WCS(hdu.header, naxis=2)
        sky_position = SkyCoord(ra, dec, unit='deg')
        if source_name == '5BZBJ1202+4444' or source_name == '5BZBJ1325+4115':
            size = [3, 3] * u.arcmin
            p = 9
        elif (source_name == '5BZBJ1419+5423'
              or source_name == '5BZBJ0945+5757'):
            size = [4, 4] * u.arcmin
            p = 12
        else:
            size = [2, 2] * u.arcmin
            p = 6

        cutout = Cutout2D(np.squeeze(hdu.data),
                          sky_position,
                          size=size,
                          wcs=wcs)
        d = cutout.data
        copy_d = np.copy(d)
        last_copy = np.copy(d)
        another_copy_d = np.copy(d)
        d[d < threshold] = 0
        d[d >= threshold] = 1
        rows, cols = d.shape

        d = label(d)  # label islands of emission
        source_islands = nearest_to_centre(d, percent=0.1)
        if source_name == '5BZBJ1000+5746':
            source_islands = [1, 2, 3, 4]
        elif source_name == '5BZBJ1202+4444':
            source_islands = [1, 2, 3]
        elif (source_name == '5BZBJ1203+5430'
              or source_name == '5BZBJ1419+5423'):
            source_islands = [1, 2]
        elif source_name == '5BZBJ1409+5939':
            source_islands = [2, 3]
        elif source_name == '5BZBJ1203+5430':
            source_islands = [1, 2]

        for source_island in source_islands:
            d[d == source_island] = dummy
        d[d != dummy] = 0
        copy_d[d != dummy] = 0
        set_to_nil = []  # identify values we can set to zero for being inside
        for r in range(rows):  # set to 0 if surrounded by non nans
            for c in range(cols):
                try:
                    if (d[r - 1, c - 1] != 0 and d[r - 1, c] != 0
                            and d[r - 1, c + 1] != 0 and d[r, c - 1] != 0
                            and d[r, c + 1] != 0 and d[r + 1, c - 1] != 0
                            and d[r + 1, c] != 0 and d[r + 1, c + 1] != 0):
                        set_to_nil.append((r, c))
                except IndexError:
                    print(f'Index error for {source_name}.')
                    continue

        for r, c in set_to_nil:
            d[r, c] = 0  # needs separate loop to avoid checkered pattern

        # d is an outline of the source (one) and everything else is zero
        # copy_d is the source with flux values and everything else is zero
        # another_copy_d has flux values throughout
        good_cells = []
        for r in range(rows):
            for c in range(cols):
                if d[r, c] != 0:
                    good_cells.append([r, c])

        x, y, r = smallestenclosingcircle.make_circle(good_cells)

        ax = plt.subplot(projection=cutout.wcs)
        plt.xlabel('Right ascension', fontsize=20, color='black')
        plt.ylabel('Declination', fontsize=20, color='black')
        ax.tick_params(axis='both', which='major', labelsize=20)
        plt.imshow(another_copy_d,
                   vmin=0,
                   vmax=np.nanmax(another_copy_d),
                   origin='lower',
                   norm=DS9Normalize(stretch='arcsinh'),
                   cmap='cubehelix_r',
                   interpolation='gaussian')
        beam = Circle((6, 6),
                      radius=2,
                      linestyle='dashed',
                      lw=2,
                      fc='none',
                      edgecolor='blue')  # radius=2 pixels -> 3" -> diameter=6"
        # diffuse = Circle((y + 0.5, x + 0.5), radius=r, fc='none',
        #                  edgecolor='k', lw=2)
        ax.add_patch(beam)
        # if comp == False:  # noqa
        #     ax.add_patch(diffuse)

        kpc_per_asec = get_kpc_per_asec(z=z)
        sbar = sbar_asec / pix  # length of scalebar in pixels
        kpc_per_pixel = kpc_per_asec * pix
        s = cutout.data.shape[1]  # plot scalebar
        plt.plot([p, p + sbar], [s - p, s - p], marker='None', lw=2, color='b')
        plt.text(p,
                 s - (5 * p / 6), f'{sbar_asec:.0f}" = '
                 f'{kpc_per_pixel * sbar:.0f} kpc',
                 fontsize=20,
                 color='b')

        cbar = plt.colorbar()
        cbar.set_label(r'Jy beam$^{-1}$', size=20)
        cbar.ax.tick_params(labelsize=20)
        plt.minorticks_on()
        plt.tick_params(which='minor', length=0)
        # levels = [level * threshold for level in [1, 2, 4, 8]]
        levels = [level * threshold for level in [1, 2, 4, 8]]
        plt.contour(another_copy_d,
                    levels=levels,
                    origin='lower',
                    colors=colors)
        plt.contour(last_copy,
                    levels=[-threshold * (3 / 5)],
                    colors='grey',
                    origin='lower',
                    linestyles='dashed')
        # plt.contour(another_copy_d - copy_d, levels=[threshold],
        #             colors='grey', origin='lower')
        saved = f'{my_directory}/images/ldr2-{source_name}.png'
        # if thresh_ans == '1/50 S_peak':
        #     plt.contour(last_copy, levels=[-four_sigma], colors='grey',
        #                 origin='lower', linestyles='dashed')
        #     plt.contour(last_copy, levels=[four_sigma], colors='grey',
        #                 origin='lower', linestyles='solid')
        print('view me: gpicview ' + saved)
        plt.savefig(saved)
        plt.clf()
        os.system(f'convert {saved} -trim {saved}')  # removes whitespace

        width = r * kpc_per_pixel * 2  # radius to diameter
        result = (f'{source_name},{ra},{dec},{rms * 1e3},{z},'
                  f'{r * pix * 2:.1f}, {width:.1f}, {pf}\n')
        print(f'{source_name[4:]}, {r * pix * 2:.4f}, {width:.4f}, '
              f'{thresh_ans}, {comp}')

        with open(results_csv, 'a') as f:
            f.write(result)
    return results_csv