Example #1
0
		# of gamma along the required axis, to calculate the observed synchrotron 
		# map. This integration is performed by the trapezoidal rule. To normalise 
		# the calculated synchrotron map, divide by the number of pixels along the 
		# z-axis. Note the array is ordered by (z,y,x)!
		# NOTE: Set dx to whatever the pixel spacing is
		sync_arr_z = np.trapz(mag_perp_gamma_z, dx = 1.0, axis = int_axis) /\
		 np.shape(mag_perp)[0]

		# Now that the synchrotron maps have been produced, we need to save the 
		# produced maps as a FITS file

		# Create a primary HDU to contain the synchrotron data
		pri_hdu = fits.PrimaryHDU(sync_arr_z)

		# Save the produced synchrotron maps as a FITS file
		mat2FITS_Image(sync_arr_z, pri_hdu.header, data_loc + 'synint_z' +\
		  '_gam{}'.format(gamma) + '.fits')

	if 'y' in line_o_sight:
		# Calculate the magnitude of the magnetic field perpendicular to the line of
		# sight, which is just the square root of the sum of the x and z component
		# magnitudes squared.
		mag_perp = np.sqrt( np.power(mag_x_data, 2.0) + np.power(mag_z_data, 2.0) )

		# Construct a variable which tells the script which axis we need to 
		# integrate along to calculate the synchrotron maps. Since the line of sight
		# is the y axis, we need to integrate along axis 1.
		int_axis = 1

		# Create a Numpy array to hold the calculated synchrotron emission map
		sync_arr_y = np.zeros((np.shape(mag_perp)[1],np.shape(mag_perp)[2]))
	# Calculate all of the first order spatial derivatives that we need
	dQ_dy, dQ_dx, dU_dy, dU_dx = calc_Sto_1Diff(StoQ, StoU, pix_sep = dl)

	# Calculate all of the second order spatial derivatives that we need
	d2Q_dy2, d2Q_dydx, d2Q_dx2, d2U_dy2, d2U_dydx, d2U_dx2 =\
	 calc_Sto_2Diff(dQ_dy, dQ_dx, dU_dy, dU_dx, pix_sep = dl)

	#------------------------- Polarisation Angle ------------------------------

	# Check to see if we need to calculate the polarisation angle
	if 'Angle' in diag_list:
		# Calculate the observed polarisation angle for this Stokes Q and U
		polar_angle = calc_Polar_Angle(StoQ, StoU)

		# Save the polarisation angle array
		mat2FITS_Image(polar_angle, StoQ_hdr, data_loc + 'PolarAngle_' +\
		 emis_mech + '.fits', clobber = True)

		# Print a message to say the diagnostic has been calculated
		print 'Polarisation angle calculated'

	#----------------------- Polarisation Gradient -----------------------------

	# Check to see if we need to calculate the polarisation gradient
	if 'Grad' in diag_list:
		# Calculate the observed polarisation gradient for this Stokes Q and U
		polar_grad = calc_Polar_Grad(dQ_dy, dQ_dx, dU_dy, dU_dx)

		# Save the polarisation gradient array
		mat2FITS_Image(polar_grad, StoQ_hdr, data_loc + 'PolarGrad_' +\
		 emis_mech + '.fits', clobber = True)
	#------------- Maximum Radial Component Directional Derivative -------------

	# Calculate the maximum value of the radial component of the directional
	# derivative at each pixel of the image, using the Stokes Q and U values
	# and their derivatives
	rad_direc_amp = calc_Rad_Direc_Amp(Sto_Q, Sto_U, dQ_dy, dQ_dx, dU_dy, dU_dx)

	# Print a message to the screen to show that the maximum of the radial
	# component of the directional derivative has been calculated successfully.
	print 'Maximum Radial Component Direc Deriv calculated successfully.'

	# Convert the matrix of maximum radial component values into a FITS file, 
	# using the header information of the CGPS data. Also save the FITS file 
	# that is produced by the function.
	rad_direc_amp_FITS = mat2FITS_Image(rad_direc_amp, cgps_Q_hdr,\
	data_loc + 'Rad_Direc_Amp_{}_smooth2_{}.fits'.format(save_append,\
	 final_res_array[i]))

	# Print a message to the screen to show that the FITS file was produced and
	# saved successfully.
	print 'FITS file successfully saved for the radial component of the '\
	 + 'directional derivative.'

	#----------- Maximum Tangential Component Directional Derivative -----------

	# Calculate the maximum value of the tangential component of the directional
	# derivative at each pixel of the image, using the Stokes Q and U values
	# and their derivatives
	tang_direc_amp = calc_Tang_Direc_Amp(Sto_Q, Sto_U, dQ_dy, dQ_dx, dU_dy, dU_dx)

	# Print a message to the screen to show that the maximum of the tangential
Example #4
0
    print 'Mach number maps calculated'

    # Now that the Mach number maps have been produced, we need to save the
    # produced map as a FITS file

    # To do this, we need to make a FITS header, so that anyone using the FITS
    # file in the future will know what gamma values were used

    # Create a primary HDU to contain the sonic Mach number data
    pri_hdu_sonic = fits.PrimaryHDU(los_sonic)

    # Create a primary HDU to contain the Alfvenic Mach data
    pri_hdu_alf = fits.PrimaryHDU(los_alf)

    # Save the produced sonic Mach number map as a FITS file
    mat2FITS_Image(los_sonic, pri_hdu_sonic.header, data_loc + 'los_av_sonic_' +\
     line_o_sight + '.fits', clobber = True)

    # Save the produced Alfvenic Mach number map as a FITS file
    mat2FITS_Image(los_alf, pri_hdu_alf.header, data_loc + 'los_av_alf_' +\
     line_o_sight + '.fits', clobber = True)

    # Close all of the fits files, to save memory
    mag_x_fits.close()
    mag_y_fits.close()
    mag_z_fits.close()
    vel_x_fits.close()
    vel_y_fits.close()
    vel_z_fits.close()
    dens_fits.close()

    # Print a message to state that the FITS file was saved successfully
Example #5
0
# Print a message to the screen to show that everything is going smoothly
print 'Stokes parameters successfully extracted from data.'

# Extract values from the S-PASS header that specify the separation between
# pixels along the x and y directions in degrees
dx = np.absolute(spass_hdr['CDELT1'])
dy = np.absolute(spass_hdr['CDELT2'])

# Calculate the polarisation intensity images for both data sets
spass_pol_inten = np.sqrt(np.power(spass_Q_data,2.0)\
 + np.power(spass_U_data,2.0))
urum_pol_inten = np.sqrt(np.power(urum_Q_data,2.0)\
 + np.power(urum_U_data,2.0))

# Save the polarisation intensity images for both data sets
mat2FITS_Image(spass_pol_inten, spass_hdr, save_loc +\
 'spass_pol_inten.fits', clobber = True)
mat2FITS_Image(urum_pol_inten, urum_hdr, save_loc +\
 'urum_pol_inten.fits', clobber = True)

#---------------------- Curvature Calculations SPASS ---------------------------

# Calculate the first order spatial derivatives of Stokes Q and U for the
# spass data
sp_dQ_dy, sp_dQ_dx, sp_dU_dy, sp_dU_dx =\
 calc_Sto_1Diff(spass_Q_data, spass_U_data, pix_sep = dy)

# Calculate all of the second order spatial derivatives of Stokes Q and U for
# the spass data
sp_d2Q_dy2, sp_d2Q_dydx, sp_d2Q_dx2, sp_d2U_dy2, sp_d2U_dydx, sp_d2U_dx2 =\
 calc_Sto_2Diff(sp_dQ_dy, sp_dQ_dx, sp_dU_dy, sp_dU_dx, pix_sep = dy)
	# Open up the FITS file
	fits_file = fits.open(cgps_loc + direc_name + fits_file_list[i])

	# Obtain the header from the FITS file
	fits_hdr = fits_file[0].header
	# Obtain the data from the FITS file
	fits_data = fits_file[0].data

	# Change the CRVAL1 value to the required value
	fits_hdr['CRVAL1'] = crval1
	# Change the CRVAL2 value to the required value
	fits_hdr['CRVAL2'] = crval2

	# Change the CRPIX1 value to the required value
	fits_hdr['CRPIX1'] = crpix1_arr[i]
	# Change the CRPIX2 value to the required value
	fits_hdr['CRPIX2'] = crpix2_arr[i]

	# Check to see if there is an EQUINOX keyword in the FITS file
	if 'EQUINOX' in fits_hdr:
		# In this case there is an EQUINOX keyword, so delete it
		del fits_hdr['EQUINOX']

	# Save the new FITS file with the modified header
	mat2FITS_Image(fits_data, fits_hdr, cgps_loc + output_direc + fits_file_list[i])

	# Print a message to the screen to say the FITS file has been made
	print "{} made successfully.".format(fits_file_list[i])

	# Close the FITS file to save memory
	fits_file.close()
Example #7
0
# Specify what the third axis is
pri_hdu_StoQ.header['CTYPE3'] = 'Spec-ind'

# Add header keywords to describe the line of sight, frequency,
# pixel size, density, velocity scale, and magnetic field scale for
# Stokes Q
pri_hdu_StoQ.header['SIM'] = (save_sim, 'simulation used')
pri_hdu_StoQ.header['LOS'] = (int_axis, '0-z, 1-y, 2-x')
pri_hdu_StoQ.header['FREQ'] = (freq, 'observing frequency (Hz)')
pri_hdu_StoQ.header['PIX-SIZE'] = (dl, 'size of each pixel (pc)')
pri_hdu_StoQ.header['DENSITY'] = (n_e, 'density scaling (cm^-3)')
pri_hdu_StoQ.header['VELSCALE'] = (v_0, 'velocity scaling (m s^-1)')
pri_hdu_StoQ.header['MAGSCALE'] = (B_0, 'magnetic field scaling (mu G)')

# Save the produced Stokes Q and U arrays as FITS files
mat2FITS_Image(StoQ, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_StoQ_specind_' + emis_mech + '.fits', clobber = True)
mat2FITS_Image(StoU, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_StoU_specind_' + emis_mech + '.fits', clobber = True)

# Save the produced polarised intensity and polarisation angle as FITS files
mat2FITS_Image(pol_inten, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_pol_inten_specind_' + emis_mech + '.fits', clobber = True)
mat2FITS_Image(pol_angle, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_pol_angle_specind_' + emis_mech + '.fits', clobber = True)

# Close all of the fits files, to save memory
dens_fits.close()
magx_fits.close()
magy_fits.close()
magz_fits.close()
Example #8
0
# Extract the data for Stokes Q, as a memory map
StoQ = StoQ_fits[0].data

# Extract the header for Stokes Q
StoQ_hdr = StoQ_fits[0].header 

# Change the value for the CRPIX1 keyword, to give the correct reference
# pixel for the new array
StoQ_hdr['CRPIX1'] = -332.00

# Extract the portion of the Stokes Q image that we are interested in
newQ = StoQ[:,:,2909:3983]

# Save the selected region of the Stokes Q image as a new FITS file
mat2FITS_Image(newQ, StoQ_hdr, data_loc +\
	 'GALFACTS_' + 'S1_chanavg_subset_Q' + '.fits', clobber = True)

# Close the Stokes Q fits file, and anything related to it, to free memory
StoQ_fits.close()
del newQ
del StoQ

# Open the FITS file that contains Stokes U, as a memory map, so that we don't
# load it all in at once.
StoU_fits = fits.open(data_loc + 'GALFACTS_S1_0263_4023_10chanavg_U.fits',\
	memmap = True)

# Extract the data for Stokes U, as a memory map
StoU = StoU_fits[0].data

# Extract the header for Stokes U
		if i == 0:
			# Set the return slice to be 0
			return_slice = 0
		else:
			# For all other cases, we need to return the second slice of the
			# array
			return_slice = 1

		# Put this slice into the storage array
		storage_arr[i] = rot_meas[return_slice]

	# Change the header to reflect what is being saved
	StoQ_hdr['OBJECT'] = 'GALFACTS_S1 Rot Meas'

	# Save the rotation measure
	mat2FITS_Image(storage_arr, StoQ_hdr, data_loc +\
	 'RotMeas_S1_chanavg_subset.fits', clobber = True)

	# Print a message to say the diagnostic has been calculated
	print 'Rotation measure calculated'

#----------------------- Wavelength Gradient ---------------------------

# Check to see if we need to calculate the wavelength gradient
if 'Wav_Grad' in diag_list:
	# Iterate over the slices of the Stokes Q and U arrays
	for i in range(num_slice):
		# Extract the current Stokes Q slice from the full array, as well as
		# the slices immediately before and after this, if they exist
		StoQ_slice = StoQ[max(0,i-1):min(i+2,num_slice)]

		# Extract the current Stokes U slice from the full array, as well as
Example #10
0
		# integrate along to calculate the map of projected magnetic field.
		# Since the line of sight is the x axis, we need to integrate along axis 2.
		int_axis = 2

	# Integrate the magnetic field strength along the required axis. This 
	# integration is performed by the trapezoidal rule. To normalise 
	# the calculated map, divide by the number of pixels along the 
	# z-axis. Note the array is ordered by (z,y,x)!
	# NOTE: Set dx to whatever the pixel spacing is
	mag_proj = np.trapz(mag_amp, dx = 1.0, axis = int_axis) /\
	 np.shape(mag_amp)[0]

	# Now that the projected magnetic field map has been produced, we need to 
	# save the produced map as a FITS file

	# To do this, we need to make a FITS header, so that anyone using the FITS
	# file in the future will know what gamma values were used

	# Create a primary HDU to contain the map of projected magnetic field
	pri_hdu = fits.PrimaryHDU(mag_proj)

	# Save the produced map of the projected magnetic field as a FITS file
	mat2FITS_Image(mag_proj, pri_hdu.header, data_loc + 'mag_proj_' +\
	 line_o_sight + '.fits')

	# Print a message to state that the FITS file was saved successfully
	print 'FITS file of projected magnetic field saved successfully'

# All of the required maps have been saved, so print a message stating that
# the script has finished
print 'All projected magnetic field calculated successfully'
Example #11
0
        # integrate along to calculate the map of projected magnetic field.
        # Since the line of sight is the x axis, we need to integrate along axis 2.
        int_axis = 2

    # Integrate the magnetic field strength along the required axis. This
    # integration is performed by the trapezoidal rule. To normalise
    # the calculated map, divide by the number of pixels along the
    # z-axis. Note the array is ordered by (z,y,x)!
    # NOTE: Set dx to whatever the pixel spacing is
    mag_proj = np.trapz(mag_amp, dx = 1.0, axis = int_axis) /\
     np.shape(mag_amp)[0]

    # Now that the projected magnetic field map has been produced, we need to
    # save the produced map as a FITS file

    # To do this, we need to make a FITS header, so that anyone using the FITS
    # file in the future will know what gamma values were used

    # Create a primary HDU to contain the map of projected magnetic field
    pri_hdu = fits.PrimaryHDU(mag_proj)

    # Save the produced map of the projected magnetic field as a FITS file
    mat2FITS_Image(mag_proj, pri_hdu.header, data_loc + 'mag_proj_' +\
     line_o_sight + '.fits')

    # Print a message to state that the FITS file was saved successfully
    print 'FITS file of projected magnetic field saved successfully'

# All of the required maps have been saved, so print a message stating that
# the script has finished
print 'All projected magnetic field calculated successfully'
Example #12
0
        # Bryan's
        division_mat[j,i] = my_data[j,i] - B_value
    
    # Print a message to the screen to show when 50 columns have been computed
    if (i+1)%50 == 0:
        # The number of columns completed is a multiple of 50, so print a 
        # message to the screen
        print '{} columns completed'.format(i+1)
        
# When the code reaches this point, both for loops have completed, and the
# division matrix is filled with values.

# Convert the matrix of divided polarisation gradient values into a FITS file,
# using the header information of my data. Also save the FITS file that is
# produced by the function.
division_FITS = mat2FITS_Image(division_mat, my_hdr,\
data_loc + 'sgps_subtract_polar_fix_unit.fits')

# Print a message to the screen to show that the FITS file was produced and
# saved successfully.
print 'FITS file successfully saved for the divided polarisation gradients.'

# Create an image of the divided polarisation gradient values
# using aplpy and the produced FITS file. This image is automatically
# saved using the given filename.
fits2aplpy(division_FITS, data_loc + 'sgps_subtract_polar_fix_unit.png', \
colour = 'RdBu')

# Print a message to the screen to show that the image of the divided 
# polarisation gradient values has been successfully produced and saved.
print 'Image of the divided polarisation gradients successfully saved.\n'
Example #13
0
    # Calculate the maximum value of the radial component of the directional
    # derivative at each pixel of the image, using the Stokes Q and U values
    # and their derivatives
    rad_direc_amp = calc_Rad_Direc_Amp(Sto_Q, Sto_U, dQ_dy, dQ_dx, dU_dy,
                                       dU_dx)

    # Print a message to the screen to show that the maximum of the radial
    # component of the directional derivative has been calculated successfully.
    print 'Maximum Radial Component Direc Deriv calculated successfully.'

    # Convert the matrix of maximum radial component values into a FITS file,
    # using the header information of the CGPS data. Also save the FITS file
    # that is produced by the function.
    rad_direc_amp_FITS = mat2FITS_Image(rad_direc_amp, cgps_Q_hdr,\
    data_loc + 'Rad_Direc_Amp_{}_smooth2_{}.fits'.format(save_append,\
     final_res_array[i]))

    # Print a message to the screen to show that the FITS file was produced and
    # saved successfully.
    print 'FITS file successfully saved for the radial component of the '\
     + 'directional derivative.'

    #----------- Maximum Tangential Component Directional Derivative -----------

    # Calculate the maximum value of the tangential component of the directional
    # derivative at each pixel of the image, using the Stokes Q and U values
    # and their derivatives
    tang_direc_amp = calc_Tang_Direc_Amp(Sto_Q, Sto_U, dQ_dy, dQ_dx, dU_dy,
                                         dU_dx)
Example #14
0
def calc_sparse_stats(input_files, output_filenames, stat_list, box_halfwidths,\
 all_fits_info = True):
    '''
	Description
        This function calculates local statistics for some pixels in an image,
        that are sparsely distributed throughout the image, using the data in
        surrounding pixels. The selected pixels will be located on a rectangular
        grid, and the spacing between the pixels is determined by the size of 
        the box used to calculate statistics, so that the input map is
        sampled as a rate greater than the Nyquist frequency. The statistics that
        are calculated can be specified in the stat_list variable. All of these 
        statistics will be calculated for each input image. Multiple input files
        can be provided, and statistics will be calculated for each image. Maps 
        of the produced statistics will be saved using the given output 
        filenames.
        
    Required Input
        input_files - An array of strings, where each string specifies the 
        			  directory and filename of the FITS image to calculate 
        			  statistics for. Local statistics are calculated for each
        			  file provided in this array.
        output_filenames - An array of strings, where each string specifies the 
        				   directory and filename to use when saving a FITS 
        				   file image of the produced statistic map. An image is
        				   saved for each input file, and each statistic. This
        				   array needs to be the same length as input_files.
        				   Each FITS file that is saved will have the type of 
        				   statistic appended to the output filename provided.
        				   The given strings should not have the .fits extension
        				   present, as this is added in the function.
        stat_list - An array of strings, where each string specifies a statistic
        			that is to be calculated locally for each input image.
        			Allowed values are 'mean', 'stdev',skewness' and 'kurtosis'.
        box_halfwidths - The half-widths of the box to use when calculating the
        				 local statistics, in pixels. This is an array of
        				 positive integers greater than or equal to 1. This 
        				 array must have the same length as input_files. Pixels 
        				 selected for the evaluation of statistics are separated
        				 by half of the box half-width.
        all_fits_info - A boolean value, if True, then all CDELT and CRPIX 
        				header info is present in the simulations, and will be 
        				used in the code. If False, then placeholder information
        				will be used.
                   
    Output
        0 - An error occurred, possibly due to inappropriate input values
        1 - Function ran to completion, and saved FITS images of the calculated
        	statistics maps successfully.
	'''

    # Check to see that the number of output filenames matches the number of
    # input filenames
    if len(input_files) != len(output_filenames):
        # In this case the number of output filenames does not match the number
        # input filenames, so the code cannot proceed. Print an error message
        # to say what has happened
        print 'ERROR: Number of input files and output filenames are different'

        # The code should not proceed in this case, so return 0
        return 0

    # Check to see that the number of box halfwidth values equals the number
    # of input filenames
    if len(input_files) != len(box_halfwidths):
        # In this case the number of box halfwidths to use does not match the
        # number of input filenames, so the code cannot proceed. Print an
        # error message to say what has happened.
        print 'ERROR: Number of input files and box halfwidths are different'

        # The code should not proceed in this case, so return 0
        return 0

    # Create a list of valid strings that can be given to the stat_list variable
    valid_stats = ['mean', 'stdev', 'skewness', 'kurtosis']

    # Check to see that valid statistics were provided
    if len(list(set(valid_stats).intersection(stat_list))) == 0:
        # In this case the array of strings given to the function does not
        # provide any valid statistics to calculate, so print an error message
        # to the screen
        print 'ERROR: No valid statistics provided to the function'

        # The code should not proceed in this case, so return 0
        return 0

    # Check to see that the values given for the box halfwidths are positive
    # integers greater than or equal to 1
    if np.any(box_halfwidths < 1):
        # In this case a value given for the box halfwidth is invalid, so
        # print an error message to the screen
        print 'ERROR: At least one of the values for box half-width is invalid'

        # The code should not proceed in this case, so return to 0
        return 0

    # Loop over the given input files, so that we can calculate statistics for
    # each one
    for i in range(len(input_files)):
        # Print a message to show that calculations are starting for the current
        # input file
        print 'Calculations starting for {}'.format(input_files[i])

        # Open the CGPS FITS file for the current resolution
        fits_file = fits.open(input_files[i])

        # Obtain the header of the primary HDU for the data
        fits_hdr = fits_file[0].header

        # Extract the data from the FITS file, which is held in the primary HDU
        fits_data = fits_file[0].data

        # Print a message to the screen saying that the data was successfully
        # extracted
        print 'CGPS data successfully extracted from the FITS file.'

        # Extract the number of pixels along the horizontal axis of the image
        num_pix_horiz = fits_hdr['NAXIS1']

        # Extract the number of pixels along the vertical axis of the image
        num_pix_vert = fits_hdr['NAXIS2']

        # If all header information is present, use the information there
        if all_fits_info == True:
            # Extract the size of each pixel from the header. This is the length of
            # each side of the pixel (assumed to be square), in degrees.
            pix_size_deg = fits_hdr['CDELT2']

            # Calculate where the reference pixel is relative to the top left
            # hand corner of the image
            horiz_centre_loc = np.absolute(fits_hdr['CDELT1'] *
                                           fits_hdr['CRPIX1'])
            vert_centre_loc = np.absolute(fits_hdr['CDELT2'] *
                                          fits_hdr['CRPIX2'])
        elif all_fits_info == False:
            # If all header information is not present, use placeholder information

            # Set the size of each pixel from the header, which is just 1
            pix_size_deg = 1.0

            # Calculate where the reference pixel is relative to the top left
            # hand corner of the image
            horiz_centre_loc = np.absolute(pix_size_deg * num_pix_horiz / 2.0)
            vert_centre_loc = np.absolute(pix_size_deg * num_pix_vert / 2.0)

        # Create a new header object, that will become the header for the
        # statistics map that is produced
        stats_hdr = fits_hdr

        # Calculate the spacing between the grid points that will be used to
        # calculate local statistics. The floor is taken just to make sure it
        # is an integer.
        grid_space = int(np.floor(box_halfwidths[i] / 2))

        # Calculate the number of grid points to place along the horizontal axis
        # A ceiling is taken to make sure we get the right integer number of
        # grid points to use
        num_grid_horiz = int(np.ceil(num_pix_horiz / grid_space))

        # Calculate the number of grid points to place along the vertical axis
        # A ceiling is taken to make sure we get the right integer number of
        # grid points to use
        num_grid_vert = int(np.ceil(num_pix_vert / grid_space))

        # Construct an array, where each entry gives the index value along the
        # horizontal axis of the grid points
        horiz_grid_indices = grid_space * np.array(range(num_grid_horiz))

        # Construct an array, where each entry gives the index value along the
        # vertical axis of the grid points
        vert_grid_indices = grid_space * np.array(range(num_grid_vert))

        # At this point the grid has been constructed, and we just need to
        # modify some of the FITS header values so that the constructed
        # statistics maps can be saved
        # Change the NAXIS keywords, that specify how many pixels are along
        # each axis of the image
        stats_hdr['NAXIS1'] = num_grid_horiz
        stats_hdr['NAXIS2'] = num_grid_vert

        # If all header information is present, use the information there
        if all_fits_info == True:
            # Change the CDELT keywords, that specify the spacing between pixels
            # in degrees
            stats_hdr['CDELT1'] = stats_hdr['CDELT1'] * grid_space
            stats_hdr['CDELT2'] = stats_hdr['CDELT2'] * grid_space

            # Change the CRPIX keywords, that specify which pixel is the reference
            # pixel in the image
            stats_hdr['CRPIX1'] = np.absolute(
                horiz_centre_loc / stats_hdr['CDELT1']) + 1
            stats_hdr['CRPIX2'] = np.absolute(vert_centre_loc /
                                              stats_hdr['CDELT2'])
        elif all_fits_info == False:
            # If all header information is not present, use placeholder information

            # Change the CDELT keywords, that specify the spacing between pixels
            # in degrees
            stats_hdr['CDELT1'] = pix_size_deg * grid_space
            stats_hdr['CDELT2'] = pix_size_deg * grid_space

            # Change the CRPIX keywords, that specify which pixel is the reference
            # pixel in the image
            stats_hdr['CRPIX1'] = np.absolute(
                horiz_centre_loc / stats_hdr['CDELT1']) + 1
            stats_hdr['CRPIX2'] = np.absolute(vert_centre_loc /
                                              stats_hdr['CDELT2'])

        # Create a dictionary that will hold the arrays corresponding to each
        # statistic
        stat_dict = {}

        # Create new numpy arrays, that have the same size as the input array.
        # These will be used to store the calculated local statistics. The
        # arrays are stored in a dictionary, with each statistic having its own
        # array
        for stat in stat_list:
            # Assign an empty array to the current statistic. Note that the data
            # type is 32-bit float, since all of the input arrays have that data
            # type
            stat_dict[stat] = np.zeros((num_grid_vert,num_grid_horiz)\
             , dtype = np.float64)

        # Loop over all of the pixels at which we will evaluate statistics,
        # starting by looping over each row
        for j in range(num_grid_vert):
            # Loop over all of the pixels in this row
            for k in range(num_grid_horiz):
                # Extract the value of the data at the current pixel
                pix_value = fits_data[vert_grid_indices[j],
                                      horiz_grid_indices[k]]

                # Calculate the index of the uppermost pixels to be included in
                # the local box. Note that the minus sign is because Python
                # indexes so that the pixels highest in the image have the
                # lowest index value
                upper_index = vert_grid_indices[j] - box_halfwidths[i]

                # Calculate the index of the lowermost pixels to be included in
                # the local box
                lower_index = vert_grid_indices[j] + box_halfwidths[i]

                # Calculate the index of the rightmost pixels to be included in
                # the local box
                right_index = horiz_grid_indices[k] + box_halfwidths[i]

                # Calculate the index of the leftmost pixels to be included in
                # the local box
                left_index = horiz_grid_indices[k] - box_halfwidths[i]

                # Check that the index of the uppermost pixel to include in the
                # local box is valid, i.e. not negative
                if upper_index < 0:
                    # In this case the value of the upper index doesn't make
                    # sense, so reset it to zero
                    upper_index = 0

                # Check that the index of the leftmost pixel to include in the
                # local box is valid, i.e. not negative
                if left_index < 0:
                    # In this case the value of the left index doesn't make
                    # sense, so reset it to zero
                    left_index = 0

                # Check that the index of the lowermost pixel to include in the
                # local box is valid, i.e. that it does not extend beyond the
                # boundaries of the image
                if lower_index >= num_pix_vert:
                    # In this case the value of the lower index doesn't make
                    # sense, so reset it to the largest possible index for the
                    # vertical axis
                    lower_index = num_pix_vert - 1

                # Check that the index of the rightmost pixel to include in the
                # local box is valid, i.e. that it does not extend beyond the
                # boundaries of the image
                if right_index >= num_pix_horiz:
                    # In this case the value of the lower index doesn't make
                    # sense, so reset it to the largest possible index for the
                    # horizontal axis
                    right_index = num_pix_horiz - 1

                # Extract the data in the local box around the current
                # pixel we are studying
                local_data = fits_data[upper_index:lower_index+1,\
                 left_index:right_index+1]

                # Flatten the local data into a one-dimensional array
                local_data_flat = local_data.flatten()

                # Find where all of the NaN values are in the local data
                NaN_position = np.isnan(local_data_flat)

                # Extract the values in the local data that are not NaN
                local_data_no_nan =\
                 local_data_flat[np.logical_not(NaN_position)]

                # Sort the local data from smallest to largest
                local_data_sorted = np.sort(local_data_no_nan)

                # Truncate the data array to the desired range
                local_data_trunc = local_data_sorted[\
                int(np.floor(0*len(local_data_sorted))):\
                int(np.floor(0.99*len(local_data_sorted)))]

                # # If we are at a desired pixel of the statistics map, then
                # # produce a histogram of the truncated data values, and save it.
                # if j==26 and (k>= 101 and k<=125):
                # 	# We are at a desired pixel, so save an image of the
                # 	# histogram at this pixel
                # 	hist_plot(local_data_trunc, output_filenames[i] +\
                # 	 '_hist_{}_{}.png'.format(j,k), 'png', 'Polar Gradient',\
                # 	 'PDF Polar Grad x={} y={}'.format(k,j), bins=20 )

                # Check that most of the data in the box is not NaN
                if (len(local_data_flat) / 2.0) > len(local_data_no_nan):
                    # In this case more than half of the data is NaN, so
                    # record NaN for any statistics that are to be calculated
                    for stat in stat_list:
                        (stat_dict[stat])[j, k] = float('nan')
                else:
                    # Check to see if the mean of the local area needs to be
                    # calculated
                    if 'mean' in stat_list:
                        # Calculate the mean of the local data that has had
                        # the NaN values removed, and store it in the
                        # corresponding array
                        (stat_dict['mean'])[j,k] =\
                         np.mean(local_data_trunc, dtype = np.float64)

                    # Check to see if the standard deviation of the local area
                    # needs to be calculated
                    if 'stdev' in stat_list:
                        # Calculate the standard deviation of the local data
                        # that has had the NaN values removed, and store it in
                        # the corresponding array
                        (stat_dict['stdev'])[j,k] =\
                         np.std(local_data_trunc, dtype = np.float64)

                    # Check to see if the skewness of the local area needs to be
                    # calculated
                    if 'skewness' in stat_list:
                        # Calculate the skewness of the local data that has had
                        # the NaN values removed, and store it in the
                        # corresponding array
                        (stat_dict['skewness'])[j,k] =\
                         stats.skew(local_data_trunc)

                    # Check to see if the kurtosis of the local area needs to be
                    # calculated
                    if 'kurtosis' in stat_list:
                        # Calculate the kurtosis of the local data that has had
                        # the NaN values removed, and store it in the
                        # corresponding array
                        (stat_dict['kurtosis'])[j,k] =\
                         stats.kurtosis(local_data_trunc)

                # When the code reaches this point, all of the required
                # statistics have been calculated for this pixel

            # When the code reaches this point, statistics have been calculated
            # for all of the pixels in this row

            # Every 20 rows, print out a message to show where the code is up to
            if (j + 1) % 20 == 0:
                # Another 20 rows have been completed, so print a message
                print '{} rows calculated'.format(j + 1)

        # When the code reaches this point, statistics have been calculated for
        # all of the pixels, for this particular value of the final resolution

        # Next, we want to save the produced maps of the local statistics

        # Loop over all of the statistics that were calculated
        for stat in stat_list:
            # Convert the matrix of values for this statistic into a FITS file,
            # and save the result using the same header as the input CGPS data.
            # The FITS file is saved in the same location as the CGPS data
            stat_FITS = mat2FITS_Image(stat_dict[stat], stats_hdr,\
             output_filenames[i] + '_{}_sparse'.format(stat) + '.fits')

            # Print a message to the screen, to show that a FITS file was
            # produced for the current statistic
            print 'FITS file saved for {}'.format(stat)

        # At this point, all FITS files have been saved for the required
        # statistics, so print a message to the screen about this
        print 'All FITS files saved for {}'.format(input_files[i])

    # When the code reaches this point, all of the FITS files have been saved
    # Print a message stating this
    print 'All FITS files saved successfully'

    # Since the code has run successfully, return 1
    return 1
	# # Save the projected Alfvenic Mach number image as a FITS file, 
	# # using the same header as was created for synchrotron intensity
	# mat2FITS_Image(los_sonic, pri_hdu_I.header, save_loc + save_sim_arr[i] + \
	#  los_loc + 'Mean_Sonic_Mach.fits', clobber = True)

	#---------------------- Projected V Field Amplitude ------------------------

	# Calculate the velocity field amplitude at each pixel
	V_amp = np.sqrt(np.power(vel_para,2.0) + np.power(vel_perp,2.0))

	# Average the amplitude of the velocity field along the line of sight
	V_amp_proj = np.mean(V_amp, axis = int_axis, dtype = np.float64)

	# Save the projected velocity field image as a FITS file, using the
	# same header as was created for synchrotron intensity
	mat2FITS_Image(V_amp_proj, pri_hdu_I.header, save_loc + save_sim_arr[i] + \
	 los_loc + 'V_amp_projected.fits', clobber = True)

	#------------------------- Projected V Parallel ----------------------------

	# Integrate the velocity field parallel to the line of sight along the
	# line of sight
	V_para_proj = np.mean(vel_para, axis = int_axis, dtype = np.float64)

	# Save the projected parallel velocity field image as a FITS file, using the
	# same header as was created for synchrotron intensity
	mat2FITS_Image(V_para_proj, pri_hdu_I.header, save_loc + save_sim_arr[i] + \
	 los_loc + 'V_para_projected.fits', clobber = True)

	#--------------------- Projected V Perpendicular ---------------------------

	# Integrate the velocity field perpendicular to the line of sight along the
# Calculate all of the first order spatial derivatives that we need
dQ_dy, dQ_dx, dU_dy, dU_dx = calc_Sto_1Diff(StoQ, StoU, pix_sep = pix_size_deg)

# Calculate all of the second order spatial derivatives that we need
d2Q_dy2, d2Q_dydx, d2Q_dx2, d2U_dy2, d2U_dydx, d2U_dx2 =\
 calc_Sto_2Diff(dQ_dy, dQ_dx, dU_dy, dU_dx, pix_sep = pix_size_deg)

#---------------------- Polarisation Intensity -------------------------

# Check to see if we need to calculate the polarisation intensity
if 'Inten' in diag_list:
	# Calculate the polarisation intensity for this Stokes Q and U
	polar_inten = calc_Polar_Inten(StoQ, StoU)

	# Save the polarisation intensity
	mat2FITS_Image(polar_inten, StoQ_hdr, data_loc +\
	 'PolarInten_' + 'S3_average' + '.fits', clobber = True)

	# Print a message to say the diagnostic has been calculated
	print 'Polarisation intensity calculated'

#------------------------- Polarisation Angle ------------------------------

# Check to see if we need to calculate the polarisation angle
if 'Angle' in diag_list:
	# Calculate the observed polarisation angle for this Stokes Q and U
	polar_angle = calc_Polar_Angle(StoQ, StoU)

	# Save the polarisation angle array
	mat2FITS_Image(polar_angle, StoQ_hdr, data_loc + 'PolarAngle_' +\
	 'S3_average' + '.fits', clobber = True)
Example #17
0
		pri_hdu.header['CRPIX3'] = 1

		# Add a header keyword to the HDU header, specifying the value of gamma
		# at the reference pixel
		pri_hdu.header['CRVAL3'] = 1.0

		# Add a header keyword to the HDU header, specifying the increment in gamma
		# along each slice of the array
		pri_hdu.header['CDELT3'] = 0.5

		# Add a header keyword to the HDU header, describing what the third axis is
		pri_hdu.header['CTYPE3'] = 'Gamma   '

		if line_o_sight == 'y':
			# Save the produced synchrotron maps as a FITS file
			mat2FITS_Image(sync_arr, pri_hdu.header, data_loc + 'synint_p1-4y_' +\
			 'rot_{}'.format(rot_ang_arr[j]) + '.fits')
		elif line_o_sight == 'z':
			# Save the produced synchrotron maps as a FITS file
			mat2FITS_Image(sync_arr, pri_hdu.header, data_loc + 'synint_p1-4_' +\
			 'rot_{}'.format(rot_ang_arr[j]) + '.fits')

		# Print a message to state that the FITS file was saved successfully
		print 'FITS file of synchrotron maps saved successfully {}'.format(rot_ang_arr[j])

	# Close all of the fits files, to save memory
	mag_x_fits.close()
	mag_y_fits.close()
	mag_z_fits.close()

	# Print a message to state that the FITS file was saved successfully
	print 'FITS file of synchrotron maps saved successfully {}'.format(sim)
Example #18
0
        pri_hdu.header['CRPIX3'] = 1

        # Add a header keyword to the HDU header, specifying the value of gamma
        # at the reference pixel
        pri_hdu.header['CRVAL3'] = 1.0

        # Add a header keyword to the HDU header, specifying the increment in gamma
        # along each slice of the array
        pri_hdu.header['CDELT3'] = 0.5

        # Add a header keyword to the HDU header, describing what the third axis is
        pri_hdu.header['CTYPE3'] = 'Gamma   '

        if line_o_sight == 'y':
            # Save the produced synchrotron maps as a FITS file
            mat2FITS_Image(sync_arr, pri_hdu.header, data_loc + 'synint_p1-4y_' +\
             'rot_{}'.format(rot_ang_arr[j]) + '.fits')
        elif line_o_sight == 'z':
            # Save the produced synchrotron maps as a FITS file
            mat2FITS_Image(sync_arr, pri_hdu.header, data_loc + 'synint_p1-4_' +\
             'rot_{}'.format(rot_ang_arr[j]) + '.fits')

        # Print a message to state that the FITS file was saved successfully
        print 'FITS file of synchrotron maps saved successfully {}'.format(
            rot_ang_arr[j])

    # Close all of the fits files, to save memory
    mag_x_fits.close()
    mag_y_fits.close()
    mag_z_fits.close()

    # Print a message to state that the FITS file was saved successfully
Example #19
0
        # Add header keywords to describe the line of sight, frequency,
        # spectral index, pixel size, density, velocity scale, and magnetic
        # field scale for Stokes U
        pri_hdu_StoU.header['SIM'] = (save_sim_arr[i], 'simulation used')
        pri_hdu_StoU.header['LOS'] = (int_axis, '0-z, 1-y, 2-x')
        pri_hdu_StoU.header['FREQ'] = (freq_backlit,
                                       'observing frequency (Hz)')
        pri_hdu_StoU.header['SPEC-IND'] = (spec_ind, 'spectral index')
        pri_hdu_StoU.header['PIX-SIZE'] = (dl, 'size of each pixel (pc)')
        pri_hdu_StoU.header['DENSITY'] = (n_e, 'density scaling (cm^-3)')
        pri_hdu_StoU.header['VELSCALE'] = (v_0, 'velocity scaling (m s^-1)')
        pri_hdu_StoU.header['MAGSCALE'] = (B_0,
                                           'magnetic field scaling (mu G)')

        # Save the produced Stokes Q and U images as FITS files
        mat2FITS_Image(StoQ, pri_hdu_StoQ.header, save_loc + save_sim_arr[i] + \
         los_loc + 'StoQ_' + 'backlit' + '.fits', clobber = True)
        mat2FITS_Image(StoU, pri_hdu_StoU.header, save_loc + save_sim_arr[i] + \
         los_loc + 'StoU_' + 'backlit' + '.fits', clobber = True)

    elif 'internal' in emis_mech:
        # In this case we need to produce cubes of Stokes Q and U for the case
        # when the emission is generated within the simulation cube, over a
        # range of frequencies

        # Create empty arrays, that will be used to contain the Stokes Q and U
        # maps created at each frequency
        StoQ = np.zeros((len(freq_internal), dens_data.shape[1],\
         dens_data.shape[2]), dtype = np.float32)
        StoU = np.zeros((len(freq_internal), dens_data.shape[1],\
         dens_data.shape[2]), dtype = np.float32)
Example #20
0
    # # Save the projected Alfvenic Mach number image as a FITS file,
    # # using the same header as was created for synchrotron intensity
    # mat2FITS_Image(los_sonic, pri_hdu_I.header, save_loc + save_sim_arr[i] + \
    #  los_loc + 'Mean_Sonic_Mach.fits', clobber = True)

    #---------------------- Projected V Field Amplitude ------------------------

    # Calculate the velocity field amplitude at each pixel
    V_amp = np.sqrt(np.power(vel_para, 2.0) + np.power(vel_perp, 2.0))

    # Average the amplitude of the velocity field along the line of sight
    V_amp_proj = np.mean(V_amp, axis=int_axis, dtype=np.float64)

    # Save the projected velocity field image as a FITS file, using the
    # same header as was created for synchrotron intensity
    mat2FITS_Image(V_amp_proj, pri_hdu_I.header, save_loc + save_sim_arr[i] + \
     los_loc + 'V_amp_projected.fits', clobber = True)

    #------------------------- Projected V Parallel ----------------------------

    # Integrate the velocity field parallel to the line of sight along the
    # line of sight
    V_para_proj = np.mean(vel_para, axis=int_axis, dtype=np.float64)

    # Save the projected parallel velocity field image as a FITS file, using the
    # same header as was created for synchrotron intensity
    mat2FITS_Image(V_para_proj, pri_hdu_I.header, save_loc + save_sim_arr[i] + \
     los_loc + 'V_para_projected.fits', clobber = True)

    #--------------------- Projected V Perpendicular ---------------------------

    # Integrate the velocity field perpendicular to the line of sight along the
Example #21
0
# Extract the data for Stokes Q, as a memory map
StoQ = StoQ_fits[0].data

# Extract the header for Stokes Q
StoQ_hdr = StoQ_fits[0].header

# Change the value for the CRPIX1 keyword, to give the correct reference
# pixel for the new array
StoQ_hdr['CRPIX1'] = -332.00

# Extract the portion of the Stokes Q image that we are interested in
newQ = StoQ[:, :, 2909:3983]

# Save the selected region of the Stokes Q image as a new FITS file
mat2FITS_Image(newQ, StoQ_hdr, data_loc +\
  'GALFACTS_' + 'S1_chanavg_subset_Q' + '.fits', clobber = True)

# Close the Stokes Q fits file, and anything related to it, to free memory
StoQ_fits.close()
del newQ
del StoQ

# Open the FITS file that contains Stokes U, as a memory map, so that we don't
# load it all in at once.
StoU_fits = fits.open(data_loc + 'GALFACTS_S1_0263_4023_10chanavg_U.fits',\
 memmap = True)

# Extract the data for Stokes U, as a memory map
StoU = StoU_fits[0].data

# Extract the header for Stokes U
Example #22
0
# Print a message to the screen to show that everything is going smoothly
print 'Stokes parameters successfully extracted from data.'

# Extract values from the S-PASS header that specify the separation between 
# pixels along the x and y directions in degrees
dx = np.absolute(spass_hdr['CDELT1'])
dy = np.absolute(spass_hdr['CDELT2'])

# Calculate the polarisation intensity images for both data sets
spass_pol_inten = np.sqrt(np.power(spass_Q_data,2.0)\
 + np.power(spass_U_data,2.0))
urum_pol_inten = np.sqrt(np.power(urum_Q_data,2.0)\
 + np.power(urum_U_data,2.0))

# Save the polarisation intensity images for both data sets
mat2FITS_Image(spass_pol_inten, spass_hdr, save_loc +\
 'spass_pol_inten.fits', clobber = True)
mat2FITS_Image(urum_pol_inten, urum_hdr, save_loc +\
 'urum_pol_inten.fits', clobber = True)

#---------------------- Curvature Calculations SPASS ---------------------------

# Calculate the first order spatial derivatives of Stokes Q and U for the 
# spass data
sp_dQ_dy, sp_dQ_dx, sp_dU_dy, sp_dU_dx =\
 calc_Sto_1Diff(spass_Q_data, spass_U_data, pix_sep = dy)

# Calculate all of the second order spatial derivatives of Stokes Q and U for
# the spass data
sp_d2Q_dy2, sp_d2Q_dydx, sp_d2Q_dx2, sp_d2U_dy2, sp_d2U_dydx, sp_d2U_dx2 =\
 calc_Sto_2Diff(sp_dQ_dy, sp_dQ_dx, sp_dU_dy, sp_dU_dx, pix_sep = dy)
# the second mask
first_mask = np.zeros(np.shape(Q_data), dtype = bool)
second_mask = np.zeros(np.shape(Q_data), dtype = bool)

# Run the generate mask function on Stokes Q, to create a mask that covers 
# all of the sources detected in Stokes Q
first_mask, second_mask = generate_mask(catalogue = Q_srclist, mask1 =\
 first_mask, mask2 = second_mask, image_loc = Sto_Q_file,\
 thresh1 = thresh1, thresh2 = thresh2)

# Run the generate mask function on Stokes U, to create a mask that covers
# all of the sources detected in Stokes U, in addition to Stokes Q
first_mask, second_mask = generate_mask(catalogue = U_srclist, mask1 =\
 first_mask, mask2 = second_mask, image_loc = Sto_U_file,\
 thresh1 = thresh1, thresh2 = thresh2)

# Cast the two masks into floats, so that they can be saved as FITS images
first_mask = first_mask.astype(np.int)
second_mask = second_mask.astype(np.int)

# Save the mask created with the first threshold as a FITS file
first_FITS = mat2FITS_Image(first_mask, Q_hdr,\
    data_loc + 'combined_mask_{}_thr_{}.fits'.format(mosaic_area, thresh1))

# Save the mask created with the second threshold as a FITS file
second_FITS = mat2FITS_Image(second_mask, Q_hdr,\
    data_loc + 'combined_mask_{}_thr_{}.fits'.format(mosaic_area, thresh2))

# At this point the required masks have been saved as FITS files, so print a 
# message saying that the program completed successfully
print 'Masks successfully saved as FITS files'
# Specify what the third axis is
pri_hdu_StoQ.header['CTYPE3'] = 'Spec-ind'

# Add header keywords to describe the line of sight, frequency,
# pixel size, density, velocity scale, and magnetic field scale for 
# Stokes Q
pri_hdu_StoQ.header['SIM'] = (save_sim, 'simulation used')
pri_hdu_StoQ.header['LOS'] = (int_axis, '0-z, 1-y, 2-x')
pri_hdu_StoQ.header['FREQ'] = (freq, 'observing frequency (Hz)')
pri_hdu_StoQ.header['PIX-SIZE'] = (dl, 'size of each pixel (pc)')
pri_hdu_StoQ.header['DENSITY'] = (n_e, 'density scaling (cm^-3)')
pri_hdu_StoQ.header['VELSCALE'] = (v_0, 'velocity scaling (m s^-1)')
pri_hdu_StoQ.header['MAGSCALE'] = (B_0, 'magnetic field scaling (mu G)')

# Save the produced Stokes Q and U arrays as FITS files
mat2FITS_Image(StoQ, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_StoQ_specind_' + emis_mech + '.fits', clobber = True)
mat2FITS_Image(StoU, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_StoU_specind_' + emis_mech + '.fits', clobber = True)

# Save the produced polarised intensity and polarisation angle as FITS files
mat2FITS_Image(pol_inten, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_pol_inten_specind_' + emis_mech + '.fits', clobber = True)
mat2FITS_Image(pol_angle, pri_hdu_StoQ.header, save_loc + save_sim + '_' + \
 line_o_sight + '_pol_angle_specind_' + emis_mech + '.fits', clobber = True)

# Close all of the fits files, to save memory
dens_fits.close()
magx_fits.close()
magy_fits.close()
magz_fits.close()
Example #25
0
	print 'Mach number maps calculated'

	# Now that the Mach number maps have been produced, we need to save the 
	# produced map as a FITS file

	# To do this, we need to make a FITS header, so that anyone using the FITS
	# file in the future will know what gamma values were used

	# Create a primary HDU to contain the sonic Mach number data
	pri_hdu_sonic = fits.PrimaryHDU(los_sonic)

	# Create a primary HDU to contain the Alfvenic Mach data
	pri_hdu_alf = fits.PrimaryHDU(los_alf)

	# Save the produced sonic Mach number map as a FITS file
	mat2FITS_Image(los_sonic, pri_hdu_sonic.header, data_loc + 'los_av_sonic_' +\
	 line_o_sight + '.fits', clobber = True)

	# Save the produced Alfvenic Mach number map as a FITS file
	mat2FITS_Image(los_alf, pri_hdu_alf.header, data_loc + 'los_av_alf_' +\
	 line_o_sight + '.fits', clobber = True)

	# Close all of the fits files, to save memory
	mag_x_fits.close()
	mag_y_fits.close()
	mag_z_fits.close()
	vel_x_fits.close()
	vel_y_fits.close()
	vel_z_fits.close()
	dens_fits.close()

	# Print a message to state that the FITS file was saved successfully
		pri_hdu_StoQ.header['MAGSCALE'] = (B_0, 'magnetic field scaling (mu G)')

		# Add header keywords to describe the line of sight, frequency,
		# spectral index, pixel size, density, velocity scale, and magnetic
		# field scale for Stokes U
		pri_hdu_StoU.header['SIM'] = (save_sim_arr[i], 'simulation used')
		pri_hdu_StoU.header['LOS'] = (int_axis, '0-z, 1-y, 2-x')
		pri_hdu_StoU.header['FREQ'] = (freq_backlit, 'observing frequency (Hz)')
		pri_hdu_StoU.header['SPEC-IND'] = (spec_ind, 'spectral index')
		pri_hdu_StoU.header['PIX-SIZE'] = (dl, 'size of each pixel (pc)')
		pri_hdu_StoU.header['DENSITY'] = (n_e, 'density scaling (cm^-3)')
		pri_hdu_StoU.header['VELSCALE'] = (v_0, 'velocity scaling (m s^-1)')
		pri_hdu_StoU.header['MAGSCALE'] = (B_0, 'magnetic field scaling (mu G)')

		# Save the produced Stokes Q and U images as FITS files
		mat2FITS_Image(StoQ, pri_hdu_StoQ.header, save_loc + save_sim_arr[i] + \
		 los_loc + 'StoQ_' + 'backlit' + '.fits', clobber = True)
		mat2FITS_Image(StoU, pri_hdu_StoU.header, save_loc + save_sim_arr[i] + \
		 los_loc + 'StoU_' + 'backlit' + '.fits', clobber = True)

	elif 'internal' in emis_mech:
		# In this case we need to produce cubes of Stokes Q and U for the case
		# when the emission is generated within the simulation cube, over a
		# range of frequencies

		# Create empty arrays, that will be used to contain the Stokes Q and U
		# maps created at each frequency
		StoQ = np.zeros((len(freq_internal), dens_data.shape[1],\
		 dens_data.shape[2]), dtype = np.float32)
		StoU = np.zeros((len(freq_internal), dens_data.shape[1],\
		 dens_data.shape[2]), dtype = np.float32)
Example #27
0
    # Calculate all of the first order spatial derivatives that we need
    dQ_dy, dQ_dx, dU_dy, dU_dx = calc_Sto_1Diff(StoQ, StoU, pix_sep=dl)

    # Calculate all of the second order spatial derivatives that we need
    d2Q_dy2, d2Q_dydx, d2Q_dx2, d2U_dy2, d2U_dydx, d2U_dx2 =\
     calc_Sto_2Diff(dQ_dy, dQ_dx, dU_dy, dU_dx, pix_sep = dl)

    #------------------------- Polarisation Angle ------------------------------

    # Check to see if we need to calculate the polarisation angle
    if 'Angle' in diag_list:
        # Calculate the observed polarisation angle for this Stokes Q and U
        polar_angle = calc_Polar_Angle(StoQ, StoU)

        # Save the polarisation angle array
        mat2FITS_Image(polar_angle, StoQ_hdr, data_loc + 'PolarAngle_' +\
         emis_mech + '.fits', clobber = True)

        # Print a message to say the diagnostic has been calculated
        print 'Polarisation angle calculated'

    #----------------------- Polarisation Gradient -----------------------------

    # Check to see if we need to calculate the polarisation gradient
    if 'Grad' in diag_list:
        # Calculate the observed polarisation gradient for this Stokes Q and U
        polar_grad = calc_Polar_Grad(dQ_dy, dQ_dx, dU_dy, dU_dx)

        # Save the polarisation gradient array
        mat2FITS_Image(polar_grad, StoQ_hdr, data_loc + 'PolarGrad_' +\
         emis_mech + '.fits', clobber = True)
Example #28
0
        if i == 0:
            # Set the return slice to be 0
            return_slice = 0
        else:
            # For all other cases, we need to return the second slice of the
            # array
            return_slice = 1

        # Put this slice into the storage array
        storage_arr[i] = rot_meas[return_slice]

    # Change the header to reflect what is being saved
    StoQ_hdr['OBJECT'] = 'GALFACTS_S1 Rot Meas'

    # Save the rotation measure
    mat2FITS_Image(storage_arr, StoQ_hdr, data_loc +\
     'RotMeas_S1_chanavg_subset.fits', clobber = True)

    # Print a message to say the diagnostic has been calculated
    print 'Rotation measure calculated'

#----------------------- Wavelength Gradient ---------------------------

# Check to see if we need to calculate the wavelength gradient
if 'Wav_Grad' in diag_list:
    # Iterate over the slices of the Stokes Q and U arrays
    for i in range(num_slice):
        # Extract the current Stokes Q slice from the full array, as well as
        # the slices immediately before and after this, if they exist
        StoQ_slice = StoQ[max(0, i - 1):min(i + 2, num_slice)]

        # Extract the current Stokes U slice from the full array, as well as
Example #29
0
# the second mask
first_mask = np.zeros(np.shape(Q_data), dtype=bool)
second_mask = np.zeros(np.shape(Q_data), dtype=bool)

# Run the generate mask function on Stokes Q, to create a mask that covers
# all of the sources detected in Stokes Q
first_mask, second_mask = generate_mask(catalogue = Q_srclist, mask1 =\
 first_mask, mask2 = second_mask, image_loc = Sto_Q_file,\
 thresh1 = thresh1, thresh2 = thresh2)

# Run the generate mask function on Stokes U, to create a mask that covers
# all of the sources detected in Stokes U, in addition to Stokes Q
first_mask, second_mask = generate_mask(catalogue = U_srclist, mask1 =\
 first_mask, mask2 = second_mask, image_loc = Sto_U_file,\
 thresh1 = thresh1, thresh2 = thresh2)

# Cast the two masks into floats, so that they can be saved as FITS images
first_mask = first_mask.astype(np.int)
second_mask = second_mask.astype(np.int)

# Save the mask created with the first threshold as a FITS file
first_FITS = mat2FITS_Image(first_mask, Q_hdr,\
    data_loc + 'combined_mask_{}_thr_{}.fits'.format(mosaic_area, thresh1))

# Save the mask created with the second threshold as a FITS file
second_FITS = mat2FITS_Image(second_mask, Q_hdr,\
    data_loc + 'combined_mask_{}_thr_{}.fits'.format(mosaic_area, thresh2))

# At this point the required masks have been saved as FITS files, so print a
# message saying that the program completed successfully
print 'Masks successfully saved as FITS files'
Example #30
0
	# along the third axis
	pri_hdu.header['CRPIX3'] = 1

	# Add a header keyword to the HDU header, specifying the value of gamma
	# at the reference pixel
	pri_hdu.header['CRVAL3'] = 1.0

	# Add a header keyword to the HDU header, specifying the increment in gamma
	# along each slice of the array
	pri_hdu.header['CDELT3'] = 0.5

	# Add a header keyword to the HDU header, describing what the third axis is
	pri_hdu.header['CTYPE3'] = 'Gamma   '

	# Save the produced synchrotron maps as a FITS file
	mat2FITS_Image(sync_arr, pri_hdu.header, data_loc + 'synint_p1-4' +\
	 line_o_sight + '.fits')

	# Close all of the fits files, to save memory
	mag_x_fits.close()
	mag_y_fits.close()
	mag_z_fits.close()

	# Print a message to state that the FITS file was saved successfully
	print 'FITS file of synchrotron maps saved successfully {}'.format(simul_arr[i])

	# # Now we wish to compare our calculated maps with Blakesley's. To do this,
	# # we will cycle through all of the synchrotron maps that have been calculated,
	# # and for each a plot will be produced of the difference between my map
	# # of synchrotron emission and Blakesley's. I will also print out the maximum 
	# # difference between the maps.
	# for i in range(len(gamma_arr)):
	print 'Polarisation gradient map calculated'

	# Now that the polarisation gradient map has been produced, we need to save the 
	# produced map as a FITS file

	# To do this, we need to make a FITS header, so that anyone using the FITS
	# file in the future will know what gamma values were used

	# Create a primary HDU to contain the rotation measure data
	pri_hdu_RM = fits.PrimaryHDU(RM_image)

	# Create a primary HDU to contain the polarisation gradient data
	pri_hdu_gradP = fits.PrimaryHDU(gradP)

	# Save the produced rotation measure map as a FITS file
	mat2FITS_Image(RM_image, pri_hdu_RM.header, data_loc + 'rot_meas_' +\
	 line_o_sight + '.fits', clobber = True)

	# Save the produced polarisation gradient map as a FITS file
	mat2FITS_Image(gradP, pri_hdu_gradP.header, data_loc + 'polar_grad_' +\
	 line_o_sight + '.fits', clobber = True)

	# Close all of the fits files, to save memory
	mag_fits.close()
	dens_fits.close()

	# Print a message to state that the FITS file was saved successfully
	print 'FITS file of gradient map saved successfully {}'.format(simul_arr[i])

# All of the required maps have been saved, so print a message stating that
# the script has finished
print 'All gradient maps calculated successfully'
        # Find the entries of the array where the measured angle was in the fourth
        # quadrant, but it is supposed to be in the third quadrant
        third_quad = np.logical_and(theta_cos_entries, double_theta_sin < 0)

        # For entries that are supposed to be in the second quadrant, adjust the
        # value of the measured angle
        double_theta_sin[second_quad] = np.pi - double_theta_sin[second_quad]

        # For entries that are supposed to be in the third quadrant, adjust the
        # value of the measured angle
        double_theta_sin[
            third_quad] = -1.0 * np.pi - double_theta_sin[third_quad]

        # Calculate the angle for which the mixed derivative is maximised,
        # at each pixel
        mix_max_ang = np.rad2deg(0.5 * double_theta_sin)

        # Save the produced angle image as a FITS file
        mat2FITS_Image(mix_max_ang, pol_angle_hdr, data_loc +\
         'MixMaxAng_backlit.fits', clobber = True)

    #---------------------------------------------------------------------------

    # Print a message to state that the FITS files were saved successfully
    print 'FITS files of projected quantities saved successfully {}'.\
    format(simul_arr[i])

# All of the required maps have been saved, so print a message stating that
# the script has finished
print 'All projected diagnostic maps calculated successfully'
-1087.00000, 2113.00000, 1313.00000, 513.00000, -287.00000, -1087.00000])

# Loop over all of the FITS files that need to be modified
for i in range(len(fits_file_list)):
    # Open up the FITS file
    fits_file = fits.open(cgps_loc + direc_name + fits_file_list[i])

    # Obtain the header from the FITS file
    fits_hdr = fits_file[0].header
    # Obtain the data from the FITS file
    fits_data = fits_file[0].data

    # Change the CRVAL1 value to the required value
    fits_hdr['CRVAL1'] = crval1
    # Change the CRVAL2 value to the required value
    fits_hdr['CRVAL2'] = crval2

    # Change the CRPIX1 value to the required value
    fits_hdr['CRPIX1'] = crpix1_arr[i]
    # Change the CRPIX2 value to the required value
    fits_hdr['CRPIX2'] = crpix2_arr[i]

    # Save the new FITS file with the modified header
    mat2FITS_Image(fits_data, fits_hdr,
                   cgps_loc + output_direc + fits_file_list[i])

    # Print a message to the screen to say the FITS file has been made
    print "{} made successfully.".format(fits_file_list[i])

    # Close the FITS file to save memory
    fits_file.close()
def calc_local_stats(input_files, output_filenames, stat_list, box_halfwidths):
    '''
	Description
        This function calculates statistics for each pixel in an image, using
        the data in surrounding pixels. The statistics that are calculated can 
        be specified in the stat_list variable. All of these statistics will
        be calculated for each input image. Multiple input files can be 
        provided, and statistics will be calculated for each image. Maps of the
        produced statistics will be saved using the given output filenames.
        
    Required Input
        input_files - An array of strings, where each string specifies the 
        			  directory and filename of the FITS image to calculate 
        			  statistics for. Local statistics are calculated for each
        			  file provided in this array.
        output_filenames - An array of strings, where each string specifies the 
        				   directory and filename to use when saving a FITS 
        				   file image of the produced statistic map. An image is
        				   saved for each input file, and each statistic. This
        				   array needs to be the same length as input_files.
        				   Each FITS file that is saved will have the type of 
        				   statistic appended to the output filename provided.
        				   The given strings should not have the .fits extension
        				   present, as this is added in the function.
        stat_list - An array of strings, where each string specifies a statistic
        			that is to be calculated locally for each input image.
        			Allowed values are 'skewness' and 'kurtosis'.
        box_halfwidths - The half-widths of the box to use when calculating the
        				 local statistics, in pixels. This is an array of
        				 positive integers greater than or equal to 1. This 
        				 array must have the same length as input_files. 
                   
    Output
        0 - An error occurred, possibly due to inappropriate input values
        1 - Function ran to completion, and saved FITS images of the calculated
        	statistics maps successfully.
	'''

    # Check to see that the number of output filenames matches the number of
    # input filenames
    if len(input_files) != len(output_filenames):
        # In this case the number of output filenames does not match the number
        # input filenames, so the code cannot proceed. Print an error message
        # to say what has happened
        print 'ERROR: Number of input files and output filenames are different'

        # The code should not proceed in this case, so return 0
        return 0

    # Check to see that the number of box halfwidth values equals the number
    # of input filenames
    if len(input_files) != len(box_halfwidths):
        # In this case the number of box halfwidths to use does not match the
        # number of input filenames, so the code cannot proceed. Print an
        # error message to say what has happened.
        print 'ERROR: Number of input files and box halfwidths are different'

        # The code should not proceed in this case, so return 0
        return 0

    # Create a list of valid strings that can be given to the stat_list variable
    valid_stats = ['skewness', 'kurtosis']

    # Check to see that valid statistics were provided
    if len(list(set(valid_stats).intersection(stat_list))) == 0:
        # In this case the array of strings given to the function does not
        # provide any valid statistics to calculate, so print an error message
        # to the screen
        print 'ERROR: No valid statistics provided to the function'

        # The code should not proceed in this case, so return 0
        return 0

    # Check to see that the values given for the box halfwidths are positive
    # integers greater than or equal to 1
    if np.any(box_halfwidths < 1):
        # In this case a value given for the box halfwidth is invalid, so
        # print an error message to the screen
        print 'ERROR: At least one of the values for box half-width is invalid'

        # The code should not proceed in this case, so return to 0
        return 0

    # Loop over the given input files, so that we can calculate statistics for
    # each one
    for i in range(len(input_files)):
        # Print a message to show that calculations are starting for the current
        # input file
        print 'Calculations starting for {}'.format(input_files[i])

        # Open the CGPS FITS file for the current resolution
        fits_file = fits.open(input_files[i])

        # Obtain the header of the primary HDU for the data
        fits_hdr = fits_file[0].header

        # Extract the data from the FITS file, which is held in the primary HDU
        fits_data = fits_file[0].data

        # Print a message to the screen saying that the data was successfully
        # extracted
        print 'CGPS data successfully extracted from the FITS file.'

        # Create a dictionary that will hold the arrays corresponding to each
        # statistic
        stat_dict = {}

        # Create new numpy arrays, that have the same size as the input array.
        # These will be used to store the calculated local statistics. The
        # arrays are stored in a dictionary, with each statistic having its own
        # array
        for stat in stat_list:
            # Assign an empty array to the current statistic. Note that the data
            # type is 32-bit float, since all of the input arrays have that data
            # type
            stat_dict[stat] = np.zeros(np.shape(fits_data), dtype=np.float32)

        # Extract the size of each pixel from the header. This is the length of
        # each side of the pixel (assumed to be square), in degrees.
        pix_size_deg = fits_hdr['CDELT2']

        # Extract the number of pixels along the horizontal axis of the image
        num_pix_horiz = fits_hdr['NAXIS1']

        # Extract the number of pixels along the vertical axis of the image
        num_pix_vert = fits_hdr['NAXIS2']

        # Loop over all of the pixels in the dataset, starting by looping over
        # each row
        for j in range(num_pix_vert):
            # Loop over all of the pixels in this row
            for k in range(num_pix_horiz):
                # Extract the value of the data at the current pixel
                pix_value = fits_data[j, k]

                # Calculate the index of the uppermost pixels to be included in
                # the local box. Note that the minus sign is because Python
                # indexes so that the pixels highest in the image have the
                # lowest index value
                upper_index = j - box_halfwidths[i]

                # Calculate the index of the lowermost pixels to be included in
                # the local box
                lower_index = j + box_halfwidths[i]

                # Calculate the index of the rightmost pixels to be included in
                # the local box
                right_index = k + box_halfwidths[i]

                # Calculate the index of the leftmost pixels to be included in
                # the local box
                left_index = k - box_halfwidths[i]

                # Check that the index of the uppermost pixel to include in the
                # local box is valid, i.e. not negative
                if upper_index < 0:
                    # In this case the value of the upper index doesn't make
                    # sense, so reset it to zero
                    upper_index = 0

                # Check that the index of the leftmost pixel to include in the
                # local box is valid, i.e. not negative
                if left_index < 0:
                    # In this case the value of the left index doesn't make
                    # sense, so reset it to zero
                    left_index = 0

                # Check that the index of the lowermost pixel to include in the
                # local box is valid, i.e. that it does not extend beyond the
                # boundaries of the image
                if lower_index >= num_pix_vert:
                    # In this case the value of the lower index doesn't make
                    # sense, so reset it to the largest possible index for the
                    # vertical axis
                    lower_index = num_pix_vert - 1

                # Check that the index of the rightmost pixel to include in the
                # local box is valid, i.e. that it does not extend beyond the
                # boundaries of the image
                if right_index >= num_pix_horiz:
                    # In this case the value of the lower index doesn't make
                    # sense, so reset it to the largest possible index for the
                    # horizontal axis
                    right_index = num_pix_horiz - 1

                # Check to see if the value of the data at this pixel is NaN
                if np.isnan(pix_value):
                    # In this case the pixel is NaN, so set the corresponding
                    # pixel in all of the statistics arrays to NaN as well
                    for stat in stat_list:
                        (stat_dict[stat])[j, k] = float('nan')

                else:
                    # In this case the pixel is not NaN, and so we can calculate
                    # local statistics at this point

                    # Extract the data in the local box around the current
                    # pixel we are studying
                    local_data = fits_data[upper_index:lower_index+1,\
                     left_index:right_index+1]

                    # Check to see if the skewness of the local area needs to be
                    # calculated
                    if 'skewness' in stat_list:
                        # Flatten the local data into a one-dimensional array
                        local_data_flat = local_data.flatten()

                        # Find where all of the NaN values are in the local data
                        NaN_position = np.isnan(local_data_flat)

                        # Extract the values in the local data that are not NaN
                        local_data_no_nan =\
                         local_data_flat[np.logical_not(NaN_position)]

                        # Calculate the skewness of the local data that has had
                        # the NaN values removed, and store it in the
                        # corresponding array
                        (stat_dict['skewness'])[j,k] =\
                         stats.skew(local_data_no_nan)

                    elif 'kurtosis' in stat_list:
                        # Flatten the local data into a one-dimensional array
                        local_data_flat = local_data.flatten()

                        # Find where all of the NaN values are in the local data
                        NaN_position = np.isnan(local_data_flat)

                        # Extract the values in the local data that are not NaN
                        local_data_no_nan =\
                         local_data_flat[np.logical_not(NaN_position)]

                        # Calculate the kurtosis of the local data that has had
                        # the NaN values removed, and store it in the
                        # corresponding array
                        (stat_dict['kurtosis'])[j,k] =\
                         stats.kurtosis(local_data_no_nan)

                # When the code reaches this point, all of the required
                # statistics have been calculated for this pixel

            # When the code reaches this point, statistics have been calculated
            # for all of the pixels in this row

            # Every 100 rows, print out a message to show where the code is up to
            if (j + 1) % 100 == 0:
                # Another 100 rows have been completed, so print a message
                print '{} rows calculated'.format(j + 1)

        # When the code reaches this point, statistics have been calculated for
        # all of the pixels, for this particular value of the final resolution

        # Next, we want to save the produced maps of the local statistics

        # Loop over all of the statistics that were calculated
        for stat in stat_list:
            # Convert the matrix of values for this statistic into a FITS file,
            # and save the result using the same header as the input CGPS data.
            # The FITS file is saved in the same location as the CGPS data
            stat_FITS = mat2FITS_Image(stat_dict[stat], fits_hdr,\
             output_filenames[i] + '_{}'.format(stat) + '.fits')

            # Print a message to the screen, to show that a FITS file was
            # produced for the current statistic
            print 'FITS file saved for {}'.format(stat)

        # At this point, all FITS files have been saved for the required
        # statistics, so print a message to the screen about this
        print 'All FITS files saved for {}'.format(input_files[i])

    # When the code reaches this point, all of the FITS files have been saved
    # Print a message stating this
    print 'All FITS files saved successfully'

    # Since the code has run successfully, return 1
    return 1
Example #35
0
    # along the third axis
    pri_hdu.header['CRPIX3'] = 1

    # Add a header keyword to the HDU header, specifying the value of gamma
    # at the reference pixel
    pri_hdu.header['CRVAL3'] = 1.0

    # Add a header keyword to the HDU header, specifying the increment in gamma
    # along each slice of the array
    pri_hdu.header['CDELT3'] = 0.5

    # Add a header keyword to the HDU header, describing what the third axis is
    pri_hdu.header['CTYPE3'] = 'Gamma   '

    # Save the produced synchrotron maps as a FITS file
    mat2FITS_Image(sync_arr, pri_hdu.header, data_loc + 'synint_p1-4' +\
     line_o_sight + '.fits')

    # Close all of the fits files, to save memory
    mag_x_fits.close()
    mag_y_fits.close()
    mag_z_fits.close()

    # Print a message to state that the FITS file was saved successfully
    print 'FITS file of synchrotron maps saved successfully {}'.format(
        simul_arr[i])

    # # Now we wish to compare our calculated maps with Blakesley's. To do this,
    # # we will cycle through all of the synchrotron maps that have been calculated,
    # # and for each a plot will be produced of the difference between my map
    # # of synchrotron emission and Blakesley's. I will also print out the maximum
    # # difference between the maps.
Example #36
0
    print 'Polarisation gradient map calculated'

    # Now that the polarisation gradient map has been produced, we need to save the
    # produced map as a FITS file

    # To do this, we need to make a FITS header, so that anyone using the FITS
    # file in the future will know what gamma values were used

    # Create a primary HDU to contain the rotation measure data
    pri_hdu_RM = fits.PrimaryHDU(RM_image)

    # Create a primary HDU to contain the polarisation gradient data
    pri_hdu_gradP = fits.PrimaryHDU(gradP)

    # Save the produced rotation measure map as a FITS file
    mat2FITS_Image(RM_image, pri_hdu_RM.header, data_loc + 'rot_meas_' +\
     line_o_sight + '.fits', clobber = True)

    # Save the produced polarisation gradient map as a FITS file
    mat2FITS_Image(gradP, pri_hdu_gradP.header, data_loc + 'polar_grad_' +\
     line_o_sight + '.fits', clobber = True)

    # Close all of the fits files, to save memory
    mag_fits.close()
    dens_fits.close()

    # Print a message to state that the FITS file was saved successfully
    print 'FITS file of gradient map saved successfully {}'.format(
        simul_arr[i])

# All of the required maps have been saved, so print a message stating that
# the script has finished
Example #37
0
        # Bryan's
        division_mat[j, i] = my_data[j, i] - B_value

    # Print a message to the screen to show when 50 columns have been computed
    if (i + 1) % 50 == 0:
        # The number of columns completed is a multiple of 50, so print a
        # message to the screen
        print '{} columns completed'.format(i + 1)

# When the code reaches this point, both for loops have completed, and the
# division matrix is filled with values.

# Convert the matrix of divided polarisation gradient values into a FITS file,
# using the header information of my data. Also save the FITS file that is
# produced by the function.
division_FITS = mat2FITS_Image(division_mat, my_hdr,\
data_loc + 'sgps_subtract_polar_fix_unit.fits')

# Print a message to the screen to show that the FITS file was produced and
# saved successfully.
print 'FITS file successfully saved for the divided polarisation gradients.'

# Create an image of the divided polarisation gradient values
# using aplpy and the produced FITS file. This image is automatically
# saved using the given filename.
fits2aplpy(division_FITS, data_loc + 'sgps_subtract_polar_fix_unit.png', \
colour = 'RdBu')

# Print a message to the screen to show that the image of the divided
# polarisation gradient values has been successfully produced and saved.
print 'Image of the divided polarisation gradients successfully saved.\n'
Example #38
0
# Calculate all of the first order spatial derivatives that we need
dQ_dy, dQ_dx, dU_dy, dU_dx = calc_Sto_1Diff(StoQ, StoU, pix_sep=pix_size_deg)

# Calculate all of the second order spatial derivatives that we need
d2Q_dy2, d2Q_dydx, d2Q_dx2, d2U_dy2, d2U_dydx, d2U_dx2 =\
 calc_Sto_2Diff(dQ_dy, dQ_dx, dU_dy, dU_dx, pix_sep = pix_size_deg)

#---------------------- Polarisation Intensity -------------------------

# Check to see if we need to calculate the polarisation intensity
if 'Inten' in diag_list:
    # Calculate the polarisation intensity for this Stokes Q and U
    polar_inten = calc_Polar_Inten(StoQ, StoU)

    # Save the polarisation intensity
    mat2FITS_Image(polar_inten, StoQ_hdr, data_loc +\
     'PolarInten_' + 'S3_average' + '.fits', clobber = True)

    # Print a message to say the diagnostic has been calculated
    print 'Polarisation intensity calculated'

#------------------------- Polarisation Angle ------------------------------

# Check to see if we need to calculate the polarisation angle
if 'Angle' in diag_list:
    # Calculate the observed polarisation angle for this Stokes Q and U
    polar_angle = calc_Polar_Angle(StoQ, StoU)

    # Save the polarisation angle array
    mat2FITS_Image(polar_angle, StoQ_hdr, data_loc + 'PolarAngle_' +\
     'S3_average' + '.fits', clobber = True)