Example #1
0
def convert_poly(poly, coords, wcs):
    '''convert the vertices of a polygon from one coordinate system to another'''
    newpoly=[]
    for vert in poly:
        if coords != 'world': #coords are in 1-indexed pixel coords
                x, y = vert[0]-1, vert[1]-1 # Convert  to 0-indexed pixel coordinates
        else: # Convert the sky coordinates to 0-indexed pixel coordinates
                pixcrd = wcs.wcs_sky2pix(np.array([vert]), 0) 
                x, y = pixcrd[0][0],pixcrd[0][1]
        newpoly.append([x,y])
    return(newpoly)
Example #2
0
def convert_poly(poly, coords, wcs):
    '''convert the vertices of a polygon from one coordinate system to another'''
    newpoly = []
    for vert in poly:
        if coords != 'world':  #coords are in 1-indexed pixel coords
            x, y = vert[0] - 1, vert[
                1] - 1  # Convert  to 0-indexed pixel coordinates
        else:  # Convert the sky coordinates to 0-indexed pixel coordinates
            pixcrd = wcs.wcs_sky2pix(np.array([vert]), 0)
            x, y = pixcrd[0][0], pixcrd[0][1]
        newpoly.append([x, y])
    return (newpoly)
Example #3
0
def radec2xy(hdr, ra, dec):
    """Transforms sky coordinates (RA and Dec) to pixel coordinates (x and y).
	
	Input:
	- hdr: FITS image header
	- ra <float> : Right ascension value in degrees
	- dec <float>: Declination value in degrees
	
	Output:
	- (x,y) <tuple>: pixel coordinates

	"""

    wcs = wcs.WCS(hdr)

    skycrd = np.array([[ra, dec]])

    pixcrd = wcs.wcs_sky2pix(skycrd, 1)

    x = pixcrd[0][0]

    y = pixcrd[0][1]

    return (x, y)
Example #4
0
def find_orientation(i,
                     fitsim,
                     ra,
                     dec,
                     Maj,
                     Min,
                     s=(3 / 60.),
                     plot=False,
                     head=None,
                     hdulist=None):
    '''	
	Finds the orientation of multiple gaussian single sources 

	To run this function for all sources, use setup_find_orientation_multiple_gaussians() instead.

	A big part of this function is a re-run of the postage function,
	since we need to make a new postage basically, but this time as an array.

	Arguments: 
	i : the new_Index of the source

	fitsim: the postage created earlier 

	ra, dec: the ra and dec of the source

	Maj: the major axis of the source

	s: the width of the image, default 3 arcmin, because it has to be a tiny bit
	lower than the postage created earlier (width 4 arcmin) or NaNs will appear in the image

	head and hdulist, the header and hdulist if a postage hasn't been created before.
	(This is so it doesn't open every time in the loop but is opened before the loop.)

	Output: 
	i, max_angle, len(err_indices)
	Which are: the new_Index of the source, the best angle of the orientation, and
	the amount of orientations that have avg flux value > 80% of the peak avg flux value along the line
	
	If plot=True, produces the plots of the best orientation and the Flux vs Orientation as well


	'''
    ################## BEGIN Postage Function #############
    if not head:
        head = pf.getheader(fitsim)
        hdulist = pf.open(fitsim)
    # Parse the WCS keywords in the primary HDU
    wcs = pw.WCS(hdulist[0].header)
    # Some pixel coordinates of interest.
    skycrd = np.array([ra, dec])
    skycrd = np.array([[ra, dec, 0, 0]], np.float_)
    # Convert pixel coordinates to world coordinates
    # The second argument is "origin" -- in this case we're declaring we
    # have 1-based (Fortran-like) coordinates.
    pixel = wcs.wcs_sky2pix(skycrd, 1)
    # Some pixel coordinates of interest.
    x = pixel[0][0]
    y = pixel[0][1]
    pixsize = abs(wcs.wcs.cdelt[0])
    if pl.isnan(s):
        s = 25.
    N = (s / pixsize)
    # print 'x=%.5f, y=%.5f, N=%i' %(x,y,N)
    ximgsize = head.get('NAXIS1')
    yimgsize = head.get('NAXIS2')
    if x == 0:
        x = ximgsize / 2
    if y == 0:
        y = yimgsize / 2
    offcentre = False
    # subimage limits: check if runs over edges
    xlim1 = x - (N / 2)
    if (xlim1 < 1):
        xlim1 = 1
        offcentre = True
    xlim2 = x + (N / 2)
    if (xlim2 > ximgsize):
        xlim2 = ximgsize
        offcentre = True
    ylim1 = y - (N / 2)
    if (ylim1 < 1):
        ylim1 = 1
        offcentre = True
    ylim2 = y + (N / 2)
    if (ylim2 > yimgsize):
        offcentre = True
        ylim2 = yimgsize

    xl = int(xlim1)
    yl = int(ylim1)
    xu = int(xlim2)
    yu = int(ylim2)
    ################## END Postage Function #############

    # extract the data array instead of making a postage stamp
    from astropy.nddata.utils import extract_array
    data_array = extract_array(hdulist[0].data, (yu - yl, xu - xl), (y, x))

    # use a radius for the line that is the major axis,
    # but with 2 pixels more added to the radius
    # to make sure we do capture the whole source
    radius = Maj / 60 * 40  #arcsec -- > arcmin --> image units
    radius = int(radius) + 2  # is chosen arbitrarily

    # in the P173+55 1 arcmin = 40 image units, should check if this is true everywhere, for FieldNames it is.

    # check if there are no NaNs in the cutout image, if there are then make smaller cutout
    if True in (np.isnan(data_array)):
        if s < (2 / 60.):
            print "No hope left for this source "
            return i, 0.0, 100.5

        elif s == (2 / 60.):
            print "Nan in the cutout image AGAIN ", head['OBJECT'], ' i = ', i
            try:
                return find_orientation(i,
                                        fitsim,
                                        ra,
                                        dec,
                                        Maj,
                                        Min,
                                        s=(Maj * 2. / 60. / 60.),
                                        plot=plot,
                                        head=head,
                                        hdulist=hdulist)
            except RuntimeError:
                print "No hope left for this source, "
                return i, 0.0, 100.5

        else:
            print "NaN in the cutout image: ", head['OBJECT'], ' i = ', i
            try:
                return find_orientation(i,
                                        fitsim,
                                        ra,
                                        dec,
                                        Maj,
                                        Min,
                                        s=(2 / 60.),
                                        plot=plot,
                                        head=head,
                                        hdulist=hdulist)
            except RuntimeError:
                print "No hope left for this source, "
                return i, 0.0, 100.5

    from scipy.ndimage import interpolation
    from scipy.ndimage import map_coordinates
    #the center of the image is at the halfway point -1 for using array-index
    xcenter = np.shape(data_array)[0] / 2 - 1  # pixel coordinates
    ycenter = np.shape(data_array)[1] / 2 - 1  # pixel coordinates

    # make a line with 'num' points and radius = radius
    x0, y0 = xcenter - radius, ycenter
    x1, y1 = xcenter + radius, ycenter
    num = 1000
    x, y = np.linspace(x0, x1, num), np.linspace(y0, y1, num)

    # the final orientation will be max_angle
    max_angle = 0
    max_value = 0
    # flux values for 0 to 179 degrees of rotation (which is also convenietly their index)
    all_values = []
    for angle in range(0, 180):
        # using spline order 3 interpolation to rotate the data by 0-180 deg
        data_array2 = interpolation.rotate(data_array,
                                           angle * 1.,
                                           reshape=False)
        # extract the values along the line,
        zi = map_coordinates(data_array2, np.vstack((y, x)), prefilter=False)
        # calc the mean flux
        meanie = np.sum(zi)
        if meanie > max_value:
            max_value = meanie
            max_angle = angle
        all_values.append(meanie)

    # calculate all orientiations for which the average flux lies within
    # 80 per cent of the peak average flux
    err_orientations = np.where(all_values > (0.8 * max_value))[0]

    # find the cutoff value, dependent on the distance
    cutoff = 2 * np.arctan(Min / Maj) * 180 / np.pi  # convert rad to deg
    if len(err_orientations) > cutoff:
        classification = 'Large err'
    else:
        classification = 'Small err'

    # then find the amount of maxima and the lobe_ratio
    from scipy.signal import argrelextrema
    data_array2 = interpolation.rotate(data_array, max_angle, reshape=False)
    zi = map_coordinates(data_array2, np.vstack((y, x)), prefilter=False)
    # find the local maxima in the flux along the line
    indx_extrema = argrelextrema(zi, np.greater)
    amount_of_maxima = len(indx_extrema[0])
    # calculate the flux ratio of the lobes
    lobe_ratio_bool = False
    lobe_ratio = 0.0  # in case there is only 1 maximum
    if amount_of_maxima > 1:
        if amount_of_maxima == 2:
            lobe_ratio = (zi[indx_extrema][0] / zi[indx_extrema][1])
        else:
            # more maxima, so the lobe_ratio is defined as the ratio between the brightest lobes
            indx_maximum_extrema = np.flip(
                np.argsort(zi[indx_extrema]),
                0)[:2]  #argsort sorts ascending so flip makes it descending
            indx_maximum_extrema = indx_extrema[0][indx_maximum_extrema]
            lobe_ratio = (zi[indx_maximum_extrema[0]] /
                          zi[indx_maximum_extrema][1])

    if plot:
        # the plot of the rotated source and the flux along the line
        fig, axes = plt.subplots(nrows=2, figsize=(12, 12))
        axes[0].imshow(data_array2, origin='lower')
        axes[0].plot([x0, x1], [y0, y1], 'r-', alpha=0.3)
        axes[1].plot(zi)
        Fratio = 10.
        if amount_of_maxima > 1:
            if ((1. / Fratio) < lobe_ratio < (Fratio)):
                lobe_ratio_bool = True

        plt.suptitle('Field: ' + head['OBJECT'] + ' | Source ' + str(i) +
                     '\n Best orientation = ' + str(max_angle) +
                     ' degrees | classification: ' + classification +
                     '\nlobe ratio ' + str(lobe_ratio_bool) + ' | extrema: ' +
                     str(indx_extrema) + '\n lobe ratio: ' + str(lobe_ratio))

        # saving the figures to seperate directories
        if amount_of_maxima == 2:
            if classification == 'Small err':
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/2_maxima/small_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '.png')  # // EDITED TO P173+55
            else:
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/2_maxima/large_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '.png')  # // EDITED TO P173+55

        elif amount_of_maxima > 2:
            if classification == 'Small err':
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/more_maxima/small_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '.png')  # // EDITED TO P173+55
            else:
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/more_maxima/large_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '.png')  # // EDITED TO P173+55

        else:
            plt.savefig(
                '/data1/osinga/figures/cutouts/P173+55/angle_distance/1_maximum/'
                + head['OBJECT'] + 'src_' + str(i) +
                '.png')  # // EDITED TO P173+55
        plt.clf()
        plt.close()

        # the plot of the flux vs orientation
        plt.plot(all_values, label='all orientations')
        plt.scatter(err_orientations,
                    np.array(all_values)[err_orientations],
                    color='y',
                    label='0.8 fraction')
        plt.axvline(x=max_angle,
                    ymin=0,
                    ymax=1,
                    color='r',
                    label='best orientation')
        plt.title('Best orientation for Source ' + str(i) +
                  '\nClassification: ' + classification + ' | Cutoff: ' +
                  str(cutoff) + ' | Error: ' + str(len(err_orientations)))
        plt.ylabel('Average flux (arbitrary units)')
        plt.xlabel('orientation (degrees)')
        plt.legend()
        plt.xlim(0, 180)
        # saving the figures to seperate directories
        if amount_of_maxima == 2:
            if classification == 'Small err':
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/2_maxima/small_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '_orientation.png')  # // EDITED TO P173+55
            else:
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/2_maxima/large_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '_orientation.png')  # // EDITED TO P173+55
        elif amount_of_maxima > 2:
            if classification == 'Small err':
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/more_maxima/small_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '_orientation.png')  # // EDITED TO P173+55
            else:
                plt.savefig(
                    '/data1/osinga/figures/cutouts/P173+55/angle_distance/more_maxima/large_err/'
                    + head['OBJECT'] + 'src_' + str(i) +
                    '_orientation.png')  # // EDITED TO P173+55

        else:
            plt.savefig(
                '/data1/osinga/figures/cutouts/P173+55/angle_distance/1_maximum/'
                + head['OBJECT'] + 'src_' + str(i) +
                '_orientation.png')  # // EDITED TO P173+55

        plt.clf()
        plt.close()
    return i, max_angle, len(
        err_orientations), amount_of_maxima, classification, lobe_ratio
Example #5
0
def postage(fitsim, postfits, ra, dec, s, NN_RA=None, NN_DEC=None):
    '''
	Makes a postage 'postfits' from the entire fitsim at RA=ra and DEC=dec with radius s (degrees)
	Creates both a 'postfits.fits' cutout as well as a 'postfits.png' image for quick viewing

	If NN_RA and NN_DEC are provided it shows an arrow from the source to the nearest neighbour.
	'''
    import os

    head = pf.getheader(fitsim)

    hdulist = pf.open(fitsim)
    # Parse the WCS keywords in the primary HDU
    wcs = pw.WCS(hdulist[0].header)

    # Some pixel coordinates of interest.
    skycrd = np.array([ra, dec])
    skycrd = np.array([[ra, dec, 0, 0]], np.float_)
    # Convert pixel coordinates to world coordinates
    # The second argument is "origin" -- in this case we're declaring we
    # have 1-based (Fortran-like) coordinates.
    pixel = wcs.wcs_sky2pix(skycrd, 1)
    # Some pixel coordinates of interest.
    x = pixel[0][0]
    y = pixel[0][1]
    pixsize = abs(wcs.wcs.cdelt[0])
    # pixsize = 0.000416666666666666 # this is what it should give for P173+55
    # but it returns 0 for pixsize, and pixel etc
    if pl.isnan(s):
        s = 25.
    N = (s / pixsize)
    print 'x=%.5f, y=%.5f, N=%i' % (x, y, N)

    ximgsize = head.get('NAXIS1')
    yimgsize = head.get('NAXIS2')

    if x == 0:
        x = ximgsize / 2
    if y == 0:
        y = yimgsize / 2

    offcentre = False
    # subimage limits: check if runs over edges
    xlim1 = x - (N / 2)
    if (xlim1 < 1):
        xlim1 = 1
        offcentre = True
    xlim2 = x + (N / 2)
    if (xlim2 > ximgsize):
        xlim2 = ximgsize
        offcentre = True
    ylim1 = y - (N / 2)
    if (ylim1 < 1):
        ylim1 = 1
        offcentre = True
    ylim2 = y + (N / 2)
    if (ylim2 > yimgsize):
        offcentre = True
        ylim2 = yimgsize

    xl = int(xlim1)
    yl = int(ylim1)
    xu = int(xlim2)
    yu = int(ylim2)
    print 'postage stamp is %i x %i pixels' % (xu - xl, yu - yl)

    from astropy.nddata.utils import extract_array

    # plt.imshow(extract_array(hdulist[0].data,(yu-yl,xu-xl),(y,x)),origin='lower')
    # plt.savefig(postfits+'.png')
    # plt.show()

    # make fits cutout
    inps = fitsim + '[%0.0f:%0.0f,%0.0f:%0.0f]' % (xl, xu, yl, yu)
    if os.path.isfile(postfits): os.system('rm ' + postfits)
    os.system('fitscopy %s %s' % (inps, postfits))
    # print  'fitscopy %s %s' %(inps,postfits)

    # make a png cutout from the fits cutout with an arrow pointing to the NN
    if NN_RA:
        gc = aplpy.FITSFigure(postfits)
        gc.show_grayscale()
        gc.add_grid()
        gc.show_arrows(ra, dec, NN_RA - ra, NN_DEC - dec)
        # gc.show_regions(prefix+file+'cat.srl.reg') #very slow
        # pl.show()
        gc.save(postfits + '.png')
        gc.close()

    return postfits
def find_orientation(i,
                     fitsim,
                     ra,
                     dec,
                     Maj,
                     s=(3 / 60.),
                     plot=False,
                     head=None,
                     hdulist=None):
    '''	
	Finds the orientation of multiple gaussian single sources 

	To run this function for all sources, use setup_find_orientation_multiple_gaussians() instead.

	A big part of this function is a re-run of the postage function,
	since we need to make a new postage basically, but this time as an array.

	Arguments: 
	i : the new_Index of the source

	fitsim: the postage created earlier 

	ra, dec: the ra and dec of the source

	Maj: the major axis of the source

	s: the width of the image, default 3 arcmin, because it has to be a tiny bit
	lower than the postage created earlier (width 4 arcmin) or NaNs will appear in the image

	head and hdulist, the header and hdulist if a postage hasn't been created before.
	(This is so it doesn't open every time in the loop but is opened before the loop.)

	Output: 
	i, max_angle, len(err_indices)
	Which are: the new_Index of the source, the best angle of the orientation, and
	the amount of orientations that have avg flux value > 80% of the peak avg flux value along the line
	
	If plot=True, produces the plots of the best orientation and the Flux vs Orientation as well


	'''
    ################## BEGIN Postage Function #############
    if not head:
        head = pf.getheader(fitsim)
        hdulist = pf.open(fitsim)
    # Parse the WCS keywords in the primary HDU
    wcs = pw.WCS(hdulist[0].header)
    # Some pixel coordinates of interest.
    skycrd = np.array([ra, dec])
    skycrd = np.array([[ra, dec, 0, 0]], np.float_)
    # Convert pixel coordinates to world coordinates
    # The second argument is "origin" -- in this case we're declaring we
    # have 1-based (Fortran-like) coordinates.
    pixel = wcs.wcs_sky2pix(skycrd, 1)
    # Some pixel coordinates of interest.
    x = pixel[0][0]
    y = pixel[0][1]
    pixsize = abs(wcs.wcs.cdelt[0])
    if pl.isnan(s):
        s = 25.
    N = (s / pixsize)
    # print 'x=%.5f, y=%.5f, N=%i' %(x,y,N)
    ximgsize = head.get('NAXIS1')
    yimgsize = head.get('NAXIS2')
    if x == 0:
        x = ximgsize / 2
    if y == 0:
        y = yimgsize / 2
    offcentre = False
    # subimage limits: check if runs over edges
    xlim1 = x - (N / 2)
    if (xlim1 < 1):
        xlim1 = 1
        offcentre = True
    xlim2 = x + (N / 2)
    if (xlim2 > ximgsize):
        xlim2 = ximgsize
        offcentre = True
    ylim1 = y - (N / 2)
    if (ylim1 < 1):
        ylim1 = 1
        offcentre = True
    ylim2 = y + (N / 2)
    if (ylim2 > yimgsize):
        offcentre = True
        ylim2 = yimgsize

    xl = int(xlim1)
    yl = int(ylim1)
    xu = int(xlim2)
    yu = int(ylim2)
    ################## END Postage Function #############

    # extract the data array instead of making a postage stamp
    from astropy.nddata.utils import extract_array
    data_array = extract_array(hdulist[0].data, (yu - yl, xu - xl), (y, x))

    # use a radius for the line that is the major axis,
    # but with 2 pixels more added to the radius
    # to make sure we do capture the whole source
    radius = Maj / 60 * 40  #arcsec -- > arcmin --> image units
    radius = int(radius) + 2  # is chosen arbitrarily

    # in the P173+55 1 arcmin = 40 image units, should check if this is true everywhere
    if True in (np.isnan(data_array)):
        if s < (2 / 60.):
            print "No hope left for this source "
            return i, 0.0, 100.5

        elif s == (2 / 60.):
            print "Nan in the cutout image AGAIN ", head['OBJECT'], ' i = ', i
            try:
                return find_orientation(i,
                                        fitsim,
                                        ra,
                                        dec,
                                        Maj,
                                        s=(Maj * 2 / 60 / 60),
                                        plot=plot,
                                        head=head,
                                        hdulist=hdulist)
            except RuntimeError:
                print "No hope left for this source, "
                return i, 0.0, 100.5

        else:
            print "NaN in the cutout image: ", head['OBJECT'], ' i = ', i
            try:
                return find_orientation(i,
                                        fitsim,
                                        ra,
                                        dec,
                                        Maj,
                                        s=(2 / 60.),
                                        plot=plot,
                                        head=head,
                                        hdulist=hdulist)
            except RuntimeError:
                print "No hope left for this source, "
                return i, 0.0, 100.5

    from scipy.ndimage import interpolation
    from scipy.ndimage import map_coordinates
    #the center of the image is at the halfway point -1 for using array-index
    xcenter = np.shape(data_array)[0] / 2 - 1  # pixel coordinates
    ycenter = np.shape(data_array)[0] / 2 - 1  # pixel coordinates

    # make a line with 'num' points and radius = radius
    x0, y0 = xcenter - radius, ycenter
    x1, y1 = xcenter + radius, ycenter
    num = 1000
    x, y = np.linspace(x0, x1, num), np.linspace(y0, y1, num)

    # make a second and third line to have a linewidth of 3
    # x0_2, y0_2 = xcenter-radius,ycenter-1
    # x1_2, y1_2 = xcenter+radius,ycenter-1
    # x0_3, y0_3 = xcenter-radius,ycenter+1
    # x1_3, y1_3 = xcenter+radius,ycenter+1
    # x2, y2 = np.linspace(x0_2,x1_2,num), np.linspace(y0_2,y1_2,num)
    # x3, y3 = np.linspace(x0_3,x1_3,num), np.linspace(y0_3,y1_3,num)

    # the final orientation will be max_angle
    max_angle = 0
    max_value = 0
    # flux values for 0 to 179 degrees of rotation (which is also convenietly their index)
    all_values = []
    for angle in range(0, 180):
        # using spline order 3 interpolation to rotate the data by 0-180 deg
        data_array2 = interpolation.rotate(data_array,
                                           angle * 1.,
                                           reshape=False)
        # extract the values along the line,
        zi = map_coordinates(data_array2, np.vstack((y, x)), prefilter=False)
        # zi2 = map_coordinates(data_array2, np.vstack((y2,x2)),prefilter=False)
        # zi3 = map_coordinates(data_array2, np.vstack((y3,x3)),prefilter=False)
        # calc the mean flux
        # zi = zi+zi2+zi3
        meanie = np.sum(zi)
        if meanie > max_value:
            max_value = meanie
            max_angle = angle
        all_values.append(meanie)

    # calculate all orientiations for which the average flux lies within
    # 80 per cent of the peak average flux
    err_orientations = np.where(all_values > (0.8 * max_value))[0]

    # print 'winner at : '
    # print max_angle, ' degrees,  average flux (random units): ' , max_value
    # print 'amount of orientations within 80 per cent : ', len(err_orientations)

    if len(err_orientations) > 15:
        classification = 'Large err'
    else:
        classification = 'Small err'

    if plot:
        data_array2 = interpolation.rotate(data_array,
                                           max_angle,
                                           reshape=False)
        plt.imshow(data_array2, origin='lower')
        plt.plot([x0, x1], [y0, y1], 'r-', alpha=0.3)
        plt.plot([x0_2, x1_2], [y0_2, y1_2], 'r-', alpha=0.3)
        plt.plot([x0_3, x1_3], [y0_3, y1_3], 'r-', alpha=0.3)
        plt.title('Field: ' + head['OBJECT'] + ' | Source ' + str(i) +
                  '\n Best orientation = ' + str(max_angle) +
                  ' degrees | classification: ' + classification)
        # plt.savefig('/data1/osinga/figures/test2_src'+str(i)+'.png')
        plt.savefig(
            '/data1/osinga/figures/cutouts/all_multiple_gaussians2/elongated/'
            + head['OBJECT'] + 'src_' + str(i) +
            '.png')  # // EDITED TO INCLUDE '2'
        plt.clf()
        plt.close()

        plt.plot(all_values, label='all orientations')
        plt.scatter(err_orientations,
                    np.array(all_values)[err_orientations],
                    color='y',
                    label='0.8 fraction')
        plt.axvline(x=max_angle,
                    ymin=0,
                    ymax=1,
                    color='r',
                    label='best orientation')
        plt.title('Best orientation for Source ' + str(i) +
                  '\nClassification: ' + classification + ' | Error: ' +
                  str(len(err_orientations)))
        plt.ylabel('Average flux (arbitrary units)')
        plt.xlabel('orientation (degrees)')
        plt.legend()
        plt.xlim(0, 180)
        # plt.savefig('/data1/osinga/figures/test2_src'+str(i)+'_orientation.png')
        plt.savefig(
            '/data1/osinga/figures/cutouts/all_multiple_gaussians2/elongated/'
            + head['OBJECT'] + 'src_' + str(i) +
            '_orientation.png')  # // EDITED TO INCLUDE '2'
        plt.clf()
        plt.close()
    return i, max_angle, len(err_orientations)