In [1]:
import utils
import core
import os
import math
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib as plt
from utils.graphing import graph
import theano
from sampled import sampled
import pymc3 as pm
import theano.tensor as tt
In [2]:
%load_ext autoreload
%autoreload 2
%matplotlib inline
In [3]:
pd.options.display.max_rows = 10
pd.options.display.float_format = '{:,.2f}'.format
plt.rcParams['figure.figsize'] = (16,12)
In [4]:
filepath = os.getcwd() + "/Data/07to1Redshift.csv"
test = core.FilteredFrame(filepath, percent_agn = ['BPT'], composite = False, include_upperlimit = True)
df = test.dataframe
In [6]:
columns = ['BPT:P(AGN)',
'O_III','O_III_Sigma','O_III_Health',
'N_II','N_II_Sigma','N_II_Health',
'H_Beta','H_Beta_Sigma','H_Beta_Health',
'H_Alpha','H_Alpha_Sigma','H_Alpha_Health',
]
lim_columns = ['BPT:P(AGN)','O_III_Health','N_II_Health', 'H_Beta_Health', 'H_Alpha_Health']
d_limits = {}
dd_limits = {}
oiii_ratio_lowLim = df['O_III_Health'].isin(['Limit']) & df['H_Beta_Health'].isin(['Healthy'])
oiii_ratio_upLim = df['O_III_Health'].isin(['Healthy']) & df['H_Beta_Health'].isin(['Limit'])
nii_ratio_lowLim = df['N_II_Health'].isin(['Limit']) & df['H_Alpha_Health'].isin(['Healthy'])
nii_ratio_upLim = df['N_II_Health'].isin(['Healthy']) & df['H_Alpha_Health'].isin(['Limit'])
oiii_healthy = df['O_III_Health'].isin(['Healthy']) & df['H_Beta_Health'].isin(['Healthy'])
nii_healthy = df['N_II_Health'].isin(['Healthy']) & df['H_Alpha_Health'].isin(['Healthy'])
oiii_limit = df[(nii_healthy & oiii_ratio_lowLim)]
nii_limit = df[(oiii_healthy & nii_ratio_lowLim)]
beta_limit = df[(nii_healthy & oiii_ratio_upLim)]
alpha_limit = df[(oiii_healthy & nii_ratio_upLim)]
d_limits['OIII'] = oiii_limit.shape[0]
d_limits['NII'] = nii_limit.shape[0]
d_limits['HBeta'] = beta_limit.shape[0]
d_limits['HAlpha'] = alpha_limit.shape[0]
o_n_limit = df[oiii_ratio_lowLim & nii_ratio_lowLim]
o_a_limit = df[oiii_ratio_lowLim & nii_ratio_upLim]
b_n_limit = df[oiii_ratio_upLim & nii_ratio_lowLim]
b_a_limit = df[oiii_ratio_upLim & nii_ratio_upLim]
dd_limits['OIII_NII'] = o_n_limit.shape[0]
dd_limits['OIII_Alpha'] = o_a_limit.shape[0]
dd_limits['Beta_NII'] = b_n_limit.shape[0]
dd_limits['Beta_Alpha'] = b_a_limit.shape[0]
print(d_limits)
print(dd_limits)
In [7]:
graph.BPT(df)
In [8]:
no_limits = df[(oiii_healthy & nii_healthy)]
graph.BPT(no_limits)
In [9]:
print('Number of Objects\n-------------\nAll Data: {}\nWell Def: {}'.format(df.shape[0],no_limits.shape[0]))
print('Loss Percentage: {0:.3f}%'.format((1-no_limits.shape[0]/df.shape[0])*100))
Lose around 9.6% of our objects
Each object on the BPT hase two ratios which are made up of two fluxes with individual sigma values.
For example a single object has the following data:
$\log_{10}(\frac{\text{O}_{\text{III}}}{\text{H}_{\beta}}) \rightarrow \left[ \begin{array}{ll} \text{O}_{\text{flux}} & \text{O}_{{\sigma}} \\ \text{H}\beta_{\text{flux}} & \text{H}\beta_{{\sigma}} \\ \end{array} \right]$
$\log_{10}(\frac{\text{N}_{\text{II}}}{\text{H}_{\alpha}}) \rightarrow \left[ \begin{array}{ll} \text{N}_{\text{flux}} & \text{N}_{{\sigma}} \\ \text{H}\alpha_{\text{flux}} & \text{H}\alpha_{{\sigma}} \\ \end{array} \right]$
In [10]:
print('OIII upLim {}\nOIII lowLim: {}\nNII upLim: {}\nNII lowLim: {}'.format(df[oiii_ratio_upLim & nii_healthy].shape[0],
df[oiii_ratio_lowLim & nii_healthy].shape[0],
df[nii_ratio_upLim & oiii_healthy].shape[0],
df[nii_ratio_lowLim & oiii_healthy].shape[0]))
$\text{flux} < \text{flux error}$
Let $f = \frac{A}{B} \text{ where } B < \sigma_B \text{, so } f = \frac{A}{\sigma_B} \text{ is an lower limit.}$
Let $f = \frac{A}{B} \text{ where } A < \sigma_A \text{, so } f = \frac{\sigma_A}{B} \text{ is an upper limit.}$
In [11]:
print(d_limits)
2D Limits:
In [12]:
print(dd_limits)
In [54]:
test_obj = df.iloc[[21226]]
test_obj[['Log(O_III/H_Beta)','Log(O_III/H_Beta)_Sigma','Log(N_II/H_Alpha)','Log(N_II/H_Alpha)_Sigma', 'O_III/H_Beta', 'H_Beta', 'H_Beta_Sigma', 'O_III']]
Out[54]:
In [15]:
graph.BPT(test_obj)
test_obj[lim_columns]
Out[15]:
In [16]:
x_test_data = [test_obj.loc[21226,'Log(N_II/H_Alpha)'],test_obj.loc[21226,'Log(N_II/H_Alpha)_Sigma'],
test_obj.loc[21226,'N_II'],test_obj.loc[21226,'N_II_Sigma'],
test_obj.loc[21226,'H_Alpha'],test_obj.loc[21226,'H_Alpha_Sigma']
]
y_test_data = [test_obj.loc[21226,'Log(O_III/H_Beta)'],test_obj.loc[21226,'Log(O_III/H_Beta)_Sigma'],
test_obj.loc[21226,'O_III'],test_obj.loc[21226,'O_III_Sigma'],
test_obj.loc[21226,'H_Beta'],test_obj.loc[21226,'H_Beta_Sigma']
]
In [17]:
@sampled
def oiii_limit(xData,yData):
x,x_sigma,x_a,x_a_sigma,x_b,x_b_sigma = xData
y,y_sigma,y_a,y_a_sigma,y_b,y_b_sigma = yData
model_x_a = pm.Normal('N_II', mu=x_a, sd = x_a_sigma)
model_x_b = pm.Normal('H_Alpha', mu=x_b, sd = x_b_sigma)
model_y_b = pm.Normal('H_Beta', mu=y_b, sd = y_b_sigma)
#the upper bound of 0.94 comes from solving ratio OIII/HBeta
model_y_a_limit = pm.Uniform('OIII_Uniform',lower =0 ,upper=0.9417)
model_y_a_gauss = pm.Normal('OIII_Normal',mu = 0.9417, sd = y_a_sigma)
y_use_limit = pm.Binomial('OIII_swap', n=1,p=0.5)
model_y_a = pm.Normal('OIII', mu = tt.switch(y_use_limit,model_y_a_limit,model_y_a_gauss), sd =1)
model_NII_HAlpha = pm.Deterministic('NII/HAlpha', model_x_a/model_x_b)
model_OIII_HBeta = pm.Deterministic('OIII/HBeta', model_y_a/model_y_b)
In [38]:
with oiii_limit(xData = x_test_data,yData =y_test_data):
base_trace = pm.sample(10000)
In [37]:
pm.traceplot(base_trace, varnames = ['OIII_Normal','OIII_Uniform'])
Out[37]:
In [26]:
def plot_jointkde(x_pdf,y_pdf):
def StarForming(x): return (1.3 + 0.61 / (x - 0.04))
g = sns.jointplot(np.log10(x_pdf),np.log10(y_pdf),kind = 'kde',size=10)
xSpan = np.linspace(-0.6, -0.1, num=200)
g.ax_joint.plot(xSpan, StarForming(xSpan), 'k--',-0.31,-0.37, 'bo')
g.set_axis_labels('Log(N_II/H_Aplha)','Log(O[III]/H_Beta)')
In [29]:
plot_jointkde(x_pdf= base_trace['NII/HAlpha'],y_pdf =base_trace['OIII/HBeta'])
In [34]:
pm.summary(base_trace)
Out[34]:
$$\log_{10}(\frac{\text{N}_{\text{II}}}{\text{H}_{\alpha}}) = -0.31 $$
$$\log_{10}(\frac{\text{N}_{\text{II}}}{\text{H}_{\alpha}}) = -0.31$$
In [51]:
def test_percentAGN(x,x_sig,y,y_sig):
def AGNLine(x): return 1.19 + 0.61 / (x - 0.47)
def SFLine(x): return 1.3 + 0.61 / (x - 0.04)
lineCorrectionAGN = 0.2
lineCorrectionSF = -0.2
x0_array = np.float64(np.ones((100,)) * -x)
y0_array = np.float64(np.ones((100,)) * -y)
xLineSpace = np.linspace((x - x_sig), (x + x_sig), 100)
yLineSpace = np.linspace((y - y_sig), (y + y_sig),
100)[:, None]
ellipse = ((xLineSpace - x) / x_sig)**2 + ((yLineSpace - y) / y_sig)**2 <= 1
boolean_AGN_line = np.subtract(
yLineSpace, AGNLine(xLineSpace)) > 0 # AGN fit line
boolean_AGN_Correction = (np.subtract(xLineSpace, np.ones(
(100, 100)) * lineCorrectionAGN) > 0) # Fixes problem with the fit line
# combines fit line and correction into single boolean array
boolean_AGN_Mask = np.where(np.logical_or(
boolean_AGN_line, boolean_AGN_Correction), True, False)
# plt.imshow(boolean_AGN_Mask, origin = 'lower') #for debugging
# Starforming Fit Lines
boolean_SF_line = np.subtract(yLineSpace, SFLine(
xLineSpace)) < 0 # Starforming fit line
boolean_SF_Correction = (np.subtract(xLineSpace, np.ones(
(100, 100)) * lineCorrectionSF) < 0) # Fixes problem with the fit line
# combines fit line and correction into single boolean array
boolean_SF_Mask = np.where(np.logical_and(
boolean_SF_line, boolean_SF_Correction), True, False)
# Neither mask indicates areas that are neither AGN or SF
boolean_Neither_Mask = np.where(np.logical_or(
boolean_SF_Mask, boolean_AGN_Mask), False, True)
# plt.imshow(boolean_SF_Mask, origin = 'lower') #for debugging
# Creat probability distribution function based on array index locations
xWeight = (np.exp(-(np.add(xLineSpace, x0_array)**2) *
(2 * x_sig**2)) * (2 * math.pi * x_sig**2))**2
yWeight = (np.exp(-(np.add(yLineSpace, y0_array)**2) *
(2 * y_sig**2)) * (2 * math.pi * y_sig**2))**2
weight_Matrix = np.sqrt(xWeight + yWeight)
# AGN total weight is the sum of weight matrix elements that are true in both the ellipse boolean mask and agn boolean mask
AGN_Weight = np.sum(
weight_Matrix[np.logical_and(ellipse, boolean_AGN_Mask)])
SF_Weight = np.sum(weight_Matrix[np.logical_and(ellipse, boolean_SF_Mask)])
Neither_Weight = np.sum(
weight_Matrix[np.logical_and(ellipse, boolean_Neither_Mask)])
# total weight of whole ellipse
Total_Weight = np.sum(weight_Matrix[ellipse])
# Percenbt AGN or starforming
AGN_Percent = AGN_Weight / Total_Weight
SF_Percent = SF_Weight / Total_Weight
Neither_Percent = Neither_Weight / Total_Weight
AGN_Percent += Neither_Percent
return AGN_Percent
In [60]:
test_obj[['BPT:P(AGN)']]
Out[60]:
In [56]:
test_percentAGN(x=-0.31,x_sig=0.03,y=-0.67,y_sig=np.log10(4.26))
Out[56]:
In [ ]: