I wrote a program that manipulated data from VLA observations and created FITS files to be used in creating spectral energy distributions of high redshift radio galaxies. I really tried to be as efficient as possible. I made lists of the variables and lists I had to use. I looped everything where I could, but it still came out horribly convoluted.
#!/usr/bin/python
import math
from astropy.io import ascii
import astropy.cosmology as cosmo
import pyfits as fits
import matplotlib.pyplot as plt
from matplotlib import lines
import numpy as np
import os
# removing any duplicates from the current directory
try:
os.system("rm -f sed_and_alpha.png")
except:
pass
try:
os.system("rm -f sed_and_alpha.fits")
except:
pass
#constants
CBAND = 4.86*10**9
XBAND = 8.46*10**9
CF = (10**-26)
#functions
def get_luminosity_distance(redshift):
'''finds luminosity distance'''
lum_dist = cosmo.luminosity_distance(redshift)
tmp = str(lum_dist)
tmp = tmp.replace("Mpc","")
tmp = float(tmp)
return tmp*3.09*10**22
print lum_dist
def get_alpha(s1,s2,v1,v2):
'''gets alpha from two flux densities'''
top = math.log10(s1/s2)
bottom = math.log10(v2/v1)
return top/bottom
def get_luminosity(D_l,z,a,nu1,nu2,Sv2):
'''gets luminosity from alpha'''
Sv2 = (Sv2/1000)*CF
lum = (4*math.pi*((D_l**2)))*(1/((1+z)**(1+a)))*((nu1/nu2)**a)*(Sv2)
return lum
#lists
available_redshifts = [] # For making sure there are no blank spaces
luminosity_distribution = [] # which calculated luminosities are available
alpha_list = [] # available alphas
new_luminosity_distribution = [] # luminosity distr. after str[-2:]
default_data = {}
list22 = []
list23 = []
list24 = []
list25 = []
list26 = []
list27 = []
list28 = []
exponent_list = [
list22,
list23,
list24,
list25,
list26,
list27,
list28,
]
exponent_list_names = [
"list22",
"list23",
"list24",
"list25",
"list26",
"list27",
"list28",
]
range_column_list = [10.0**22, 10.0**23, 10.0**24,10.0**25,10.0**26,10.0**27,10.0**28]
ylist = []
num_galaxies_list = []
filename = "/home/vhx/Documents/code/python/fits/radio_template.fits/apj384116t3_mrt.txt"
table_data = ascii.read(filename) # getting the table data
# Determining which redshifts are available
for i in xrange(246):
blank = True
tmp = (table_data["z"][i])
if tmp != 'NO' and table_data["SX"][i] != 'NO' and table_data["SC"][i] != 'NO':
available_redshifts.append(i)
else:
pass
# get the spectral indices
for i in range(len(available_redshifts)-1):
alpha_list.append(get_alpha(table_data["SX"][available_redshifts[i]],table_data["SC"][available_redshifts[i]],XBAND,CBAND))
print table_data["z"][available_redshifts[i]], table_data["SX"][available_redshifts[i]], table_data["SC"][available_redshifts[i]]
# solving for luminosity
for i in range(len(available_redshifts)-1):
x = get_luminosity_distance(table_data["z"][available_redshifts[i]])
luminosity_distribution.append(get_luminosity(x,table_data["z"][available_redshifts[i]],alpha_list[i],CBAND,XBAND,table_data["SX"][available_redshifts[i]]))
# removing the units from the luminosity distribution so it can be converted
for z in range(len(luminosity_distribution)-1):
tmp = str(luminosity_distribution[z])
new_tmp = tmp.replace("Mpc","")
print new_tmp
try:
new_luminosity_distribution.append(float(new_tmp))
except ValueError:
print 'Found blank space!'
pass
new_luminosity_distribution.pop(0)
# checking stuff
alpha_list[:] = [x for x in alpha_list if math.isnan(x) != True]
print alpha_list
k = 0
for item in alpha_list:
k += item
print k/(len(alpha_list)-1)
print max(alpha_list),min(alpha_list)
print '\n'*5
for item in new_luminosity_distribution:
print '%e' % item
print '%e, %e' % (max(new_luminosity_distribution), min(new_luminosity_distribution))
sum = 0
for item in new_luminosity_distribution:
sum += item
print sum/len(new_luminosity_distribution)
new_luminosity_distribution_array = np.array(new_luminosity_distribution)
alpha_list_array = np.array(alpha_list)
numbers = np.random.normal(size = 1000)
width = 1
zed = 0
#making new_luminosity_dist. and alpha_list equal in length
print len(new_luminosity_distribution), len(alpha_list)
alpha_list.pop()
alpha_list.pop()
# checking the range of exponent values
for i in range(len(new_luminosity_distribution)-1):
tmp = str(new_luminosity_distribution[i])
tmp = tmp[-2:]
if int(tmp) == 22:
list22.append(i)
elif int(tmp) == 23:
list23.append(i)
elif int(tmp) == 24:
list24.append(i)
elif int(tmp) == 25:
list25.append(i)
elif int(tmp) == 26:
list26.append(i)
elif int(tmp) == 27:
list27.append(i)
elif int(tmp) == 28:
list28.append(i)
for lists in exponent_list:
print lists
# grouping average alphas
for i in range(len(exponent_list)-1):
sum = 0
for item in exponent_list[i]:
sum += alpha_list[item]
try:
sum /= len(exponent_list[i])
ylist.append(sum)
except ZeroDivisionError:
sum = 0
average_dictionary["average of "+str(exponent_list_names[i])] = sum
print average_dictionary
# making the bar graph
for zed in range(len(exponent_list)-1):
current_list = exponent_list[zed]
item = 0
try:
x = str(new_luminosity_distribution[current_list[item]])
x = int(x[-2:])
except:
x = 0
height = len(current_list)
plt.bar(x,height,width,color = 'gray')
for item in exponent_list:
num_galaxies_list.append(len(item))
#annotating the alphas
plt.annotate("alpha = \n"+str(average_dictionary['average of list22']),xy = (22,5),xytext = (22.3,10),rotation = 90)
plt.annotate("alpha = \n"+str(average_dictionary['average of list24']),xy = (24,5),xytext = (24.3,15),rotation = 90)
plt.annotate("alpha = \n"+str(average_dictionary['average of list25']),xy = (25,5),xytext = (25.3,20),rotation = 90)
plt.annotate("alpha = \n"+str(average_dictionary['average of list26']),xy = (22,5),xytext = (26.3,20),rotation = 90)
plt.annotate("alpha = \n"+str(average_dictionary['average of list22']),xy = (22,5),xytext = (27.3,20),rotation = 90)
plt.savefig("sed_and_alpha")
# Putting everything into a FITS file
hdu = fits.PrimaryHDU()
hdulist = fits.HDUList([hdu])
range_column = fits.Column(name = 'Range', format = 'FLOAT',
array = range_column_list)
num_galaxies = fits.Column(name = 'Number of Galaxies', format = 'FLOAT',array = num_galaxies_list)
mean_alpha_column = fits.Column(name = 'mean_alpha', format = 'FLOAT', array = ylist)
mean_alpha = fits.ColDefs([range_column,mean_alpha_column,num_galaxies])
alpha_change = fits.new_table(mean_alpha)
alpha_change.header.update('EXTNAME','ALPHACHANGE','mapping the change of spectral index')
primary_header = fits.Header()
primary_header.append('LUMINOS')
for item in range_column_list:
primary_header.append(str(item))
primary_hdu = fits.PrimaryHDU(header = primary_header)
thdulist = fits.HDUList([primary_hdu,alpha_change])
thdulist.writeto("sed_and_alpha.fits")
print '<====DONE====>'
Questions:
- Is there anything that can be done to make it more efficient?
- Can list comprehension be used to make anything shorter?
- Is it good code? Have I improved from my past posts?
Note: nothing can be done to shorten the plt.annotate
block--the values are arbitrary (but not random).
list[2][2]
orlist[22]
instead oflist22
and then using loops instead of elifs. But not sure that'll make your code any faster, just shorter. \$\endgroup\$ – user1149 Feb 9 '16 at 18:33list[22]
is the power that the luminosity is raised to, i.e 10^x, where the variable islist[x]
. \$\endgroup\$ – Joseph Farah Feb 9 '16 at 19:05