def compute_BluePoints(self, lineslog_frame, Wmin, Wmax, Lambda_Match): #Wavelength limits for the blue lines Blue_limit = Wmin + self.SpectraEdges_Limit Red_limit = Lambda_Match - self.SpectraEdges_Limit BlueH_indx = lineslog_frame.index[in1d(lineslog_frame['Ion'], self.RecombRatios_Ions) & (lineslog_frame['TheoWavelength'] > Blue_limit) & (lineslog_frame['TheoWavelength'] < Red_limit)] Obs_Blue_Ions = lineslog_frame.loc[BlueH_indx, 'Ion'].values #Check in case we do not have enough emission lines if len(Obs_Blue_Ions) >= 2: #Declare normalizing emission (Blue spectra always HBeta) N_line_flux = lineslog_frame.loc['H1_4861A']['line_Flux'] N_line_f = lineslog_frame.loc['H1_4861A']['line_f'] N_line_Ion = lineslog_frame.loc['H1_4861A']['Ion'] #Calculate theoretical and observational ratios Desplacement_constant = ufloat(N_line_flux.nominal_value, N_line_flux.std_dev) #This is not completelety mathematically correct but avoids a zero sigma Theo_RecomRatio = lineslog_frame.loc[BlueH_indx, 'line_TheoRecombRatio'].values Obs_RecombRatio = lineslog_frame.loc[BlueH_indx, 'line_Flux'].values / Desplacement_constant #Generate x_true and y axis arrays for the plot x_Blue = lineslog_frame.loc[BlueH_indx, 'line_f'].values - N_line_f y_Blue = unum_log10(Theo_RecomRatio) - unum_log10(Obs_RecombRatio) return x_Blue, y_Blue, list(Obs_Blue_Ions), N_line_Ion else: return None, None, None, None
def compute_inBoundaryPoints(self, lineslog_frame, Obs_indeces, Wmin, Wmax): #Generating the unumpy array for the error propagation Theo_RecomRatio = lineslog_frame.loc[Obs_indeces, 'line_TheoRecombRatio'].values Obs_RecombRatio = lineslog_frame.loc[Obs_indeces, 'line_Flux'].values / lineslog_frame.loc['H1_4861A']['line_Flux'] #Generate x_true and y axis arrays for the plot x_total = lineslog_frame.loc[Obs_indeces, 'line_f'].values - lineslog_frame.loc['H1_4861A']['line_f'] y_total = unum_log10(Theo_RecomRatio) - unum_log10(Obs_RecombRatio) Obs_Ions = lineslog_frame.loc[Obs_indeces, 'Ion'].values Obs_Wavelength = lineslog_frame.loc[Obs_indeces, 'TheoWavelength'].values #Emission lines outside the edges Obs_InBoundary_Indx = where((Obs_Wavelength > (Wmin + self.SpectraEdges_Limit)) & (Obs_Wavelength < (Wmax - self.SpectraEdges_Limit)))[0] x_inboundary = x_total[Obs_InBoundary_Indx] y_inboundary = y_total[Obs_InBoundary_Indx] Obs_Ions_inBoundary = Obs_Ions[Obs_InBoundary_Indx] #Emission lines inside the edges Obs_OutBoundary_Indx = where((Obs_Wavelength < (Wmin + self.SpectraEdges_Limit)) | (Obs_Wavelength > (Wmax - self.SpectraEdges_Limit)))[0] x_outboundary = x_total[Obs_OutBoundary_Indx] y_outboundary = y_total[Obs_OutBoundary_Indx] Obs_Ions_outBoundary = Obs_Ions[Obs_OutBoundary_Indx] return x_inboundary, y_inboundary, Obs_Ions_inBoundary, x_outboundary, y_outboundary, Obs_Ions_outBoundary
def compute_allpoints(self, lineslog_frame, Obs_indeces): #Generating the unumpy array for the error propagation Theo_RecomRatio = lineslog_frame.loc[Obs_indeces, 'line_TheoRecombRatio'].values Obs_RecombRatio = lineslog_frame.loc[Obs_indeces, 'line_Flux'].values / lineslog_frame.loc['H1_4861A']['line_Flux'] #Generate x_true and y axis arrays for the plot x_total = lineslog_frame.loc[Obs_indeces, 'line_f'].values - lineslog_frame.loc['H1_4861A']['line_f'] y_total = unum_log10(Theo_RecomRatio) - unum_log10(Obs_RecombRatio) return x_total, y_total
def compute_RedPoints(self, lineslog_frame, Wmin, Wmax, Lambda_Match): #Wavelength limits for the red lines Blue_limit = Wmax - self.SpectraEdges_Limit Red_limit = Lambda_Match + self.SpectraEdges_Limit RedH_indx = lineslog_frame.index[in1d(lineslog_frame['Ion'], self.RecombRatios_Ions) & (lineslog_frame['TheoWavelength'] > Red_limit) & (lineslog_frame['TheoWavelength'] < Blue_limit)] Obs_Red_Ions = lineslog_frame.loc[RedH_indx, 'Ion'].values #Check in case we do not have enough emission lines if len(Obs_Red_Ions) >= 2: #Declare normalizing emission (Blue spectra always HBeta) Hbeta_line_f = lineslog_frame.loc['H1_4861A']['line_f'] Hbeta_line_Emis = lineslog_frame.loc['H1_4861A']['line_Emissivity'] #Declare normalizing emission (in red spectra is the strongest emission ) N_line_idx = lineslog_frame.loc[RedH_indx]['Flux_Int'].idxmax() #We do not use line_flux because it is a ufloat and it does not work with idxmax N_line_flux = lineslog_frame.loc[N_line_idx]['line_Flux'] N_line_Ion = lineslog_frame.loc[N_line_idx]['Ion'] N_line_Emis = lineslog_frame.loc[N_line_idx]['line_Emissivity'] #Determine theoretical intensity line ratios Desplacement_constant = ufloat(N_line_flux.nominal_value * Hbeta_line_Emis / N_line_Emis, N_line_flux.std_dev * Hbeta_line_Emis / N_line_Emis) Theo_RecomRatio_Red = lineslog_frame.loc[RedH_indx, 'line_TheoRecombRatio'].values Obs_RecombRatio_Red = lineslog_frame.loc[RedH_indx, 'line_Flux'].values / Desplacement_constant #Generate x_true and y axis arrays for the plot x_Red = lineslog_frame.loc[RedH_indx, 'line_f'].values - Hbeta_line_f y_Red = unum_log10(Theo_RecomRatio_Red) - unum_log10(Obs_RecombRatio_Red) return x_Red, y_Red, list(Obs_Red_Ions), N_line_Ion #Case we only have one red emission line... observation (most likely Halpha) else: return None, None, None, None
def compare_RecombCoeffs(self, obj_data, lineslog_frame, spectral_limit=200): # Create hidrogen atom object self.H1_atom = RecAtom('H', 1) linformat_df = read_csv( '/home/vital/workspace/dazer/format/emlines_pyneb_optical_infrared.dz', index_col=0, names=['ion', 'lambda_theo', 'latex_format'], delim_whitespace=True) lineslog_frame['latex_format'] = 'none' for line in lineslog_frame.index: if '_w' not in line: # Structure to avoid wide components lineslog_frame.loc[line, 'latex_format'] = r'${}$'.format( linformat_df.loc[line, 'latex_format']) # Load electron temperature and density (if not available it will use Te = 10000K and ne = 100cm^-3) T_e = self.checking_for_ufloat(obj_data.TeSIII) if ~isnan( self.checking_for_ufloat(obj_data.TeSIII)) else 10000.0 n_e = self.checking_for_ufloat(obj_data.neSII) if ~isnan( self.checking_for_ufloat(obj_data.neSII)) else 100.0 # Get the Hidrogen recombination lines that we have observed in this object Obs_Hindx = lineslog_frame.Ion.isin(self.RecombRatios_Ions) # Calculate recombination coefficients and reddening curve values Obs_H_Emis = empty(len(Obs_Hindx)) Obs_Ions = lineslog_frame.loc[Obs_Hindx, 'Ion'].values for i in range(len(Obs_Ions)): TransitionCode = Obs_Ions[i][Obs_Ions[i].find('_') + 1:len(Obs_Ions[i])] Obs_H_Emis[i] = self.H1_atom.getEmissivity(tem=T_e, den=n_e, label=TransitionCode) # Normalize by Hbeta (this new constant is necessary to avoid a zero sigma) Hbeta_Emis = self.H1_atom.getEmissivity(tem=T_e, den=n_e, label='4_2') Fbeta_flux = ufloat( lineslog_frame.loc['H1_4861A']['line_Flux'].nominal_value, lineslog_frame.loc['H1_4861A']['line_Flux'].std_dev) # Load theoretical and observational recombination ratios to data frame lineslog_frame.loc[Obs_Hindx, 'line_Emissivity'] = Obs_H_Emis lineslog_frame.loc[Obs_Hindx, 'line_TheoRecombRatio'] = Obs_H_Emis / Hbeta_Emis lineslog_frame.loc[Obs_Hindx, 'line_ObsRecombRatio'] = lineslog_frame.loc[ Obs_Hindx, 'line_Flux'].values / Fbeta_flux # Get indeces of emissions in each arm ObsBlue_Hindx = Obs_Hindx & (lineslog_frame.lambda_theo < obj_data.join_wavelength) ObsRed_Hindx = Obs_Hindx & (lineslog_frame.lambda_theo > obj_data.join_wavelength) # Recalculate red arm coefficients so they are normalized by red arm line (the most intense) if (ObsRed_Hindx.sum() ) > 0: # Can only work if there is at least one line idx_Redmax = lineslog_frame.loc[ObsRed_Hindx]['flux_intg'].idxmax( ) # We do not use line_flux because it is a ufloat and it does not work with idxmax H_Redmax_flux = lineslog_frame.loc[idx_Redmax, 'line_Flux'] H_Redmax_emis = lineslog_frame.loc[idx_Redmax, 'line_Emissivity'] Flux_Redmax = ufloat( H_Redmax_flux.nominal_value * Hbeta_Emis / H_Redmax_emis, H_Redmax_flux.std_dev * Hbeta_Emis / H_Redmax_emis) lineslog_frame.loc[ObsRed_Hindx, 'line_ObsRecombRatio'] = lineslog_frame.loc[ ObsRed_Hindx, 'line_Flux'].values / Flux_Redmax # Load x axis values: (f_lambda - f_Hbeta) and y axis values: log(F/Fbeta)_theo - log(F/Fbeta)_obs to dataframe lineslog_frame.loc[Obs_Hindx, 'x axis values'] = lineslog_frame.loc[Obs_Hindx, 'line_f'].values - \ lineslog_frame.loc['H1_4861A']['line_f'] lineslog_frame.loc[Obs_Hindx, 'y axis values'] = unum_log10( lineslog_frame.loc[Obs_Hindx, 'line_TheoRecombRatio'].values ) - unum_log10(lineslog_frame.loc[Obs_Hindx, 'line_ObsRecombRatio'].values) # Compute all the possible configuration of points and store them output_dict = {} # --- All points: output_dict['all_x'] = lineslog_frame.loc[Obs_Hindx, 'x axis values'].values output_dict['all_y'] = lineslog_frame.loc[Obs_Hindx, 'y axis values'].values output_dict['all_ions'] = list( lineslog_frame.loc[Obs_Hindx, 'latex_format'].values) # --- By arm output_dict['blue_x'] = lineslog_frame.loc[ObsBlue_Hindx, 'x axis values'].values output_dict['blue_y'] = lineslog_frame.loc[ObsBlue_Hindx, 'y axis values'].values output_dict['blue_ions'] = list( lineslog_frame.loc[ObsBlue_Hindx, 'latex_format'].values) output_dict['red_x'] = lineslog_frame.loc[ObsRed_Hindx, 'x axis values'].values output_dict['red_y'] = lineslog_frame.loc[ObsRed_Hindx, 'y axis values'].values output_dict['red_ions'] = list( lineslog_frame.loc[ObsRed_Hindx, 'latex_format'].values) # --- Store fluxes output_dict['Blue_ObsRatio'] = unum_log10( lineslog_frame.loc[ObsBlue_Hindx, 'line_ObsRecombRatio'].values) output_dict['Red_ObsRatio'] = unum_log10( lineslog_frame.loc[ObsRed_Hindx, 'line_ObsRecombRatio'].values) output_dict['line_Flux_Blue'] = lineslog_frame.loc[ObsBlue_Hindx, 'line_Flux'].values output_dict['line_Flux_Red'] = lineslog_frame.loc[ObsRed_Hindx, 'line_Flux'].values output_dict['line_wave_Blue'] = lineslog_frame.loc[ ObsBlue_Hindx, 'lambda_theo'].values output_dict['line_wave_Red'] = lineslog_frame.loc[ObsRed_Hindx, 'lambda_theo'].values # --- Inside limits if obj_data.h_gamma_valid == 'yes': in_idcs = Obs_Hindx elif obj_data.h_gamma_valid == 'no': wave_idx = ((lineslog_frame.lambda_theo > (obj_data.Wmin_Blue + spectral_limit)) & ( lineslog_frame.lambda_theo < (obj_data.join_wavelength - spectral_limit))) \ | ((lineslog_frame.lambda_theo > (obj_data.join_wavelength + spectral_limit)) & ( lineslog_frame.lambda_theo < (obj_data.Wmax_Red - spectral_limit))) in_idcs = Obs_Hindx & wave_idx output_dict['in_x'] = lineslog_frame.loc[in_idcs, 'x axis values'].values output_dict['in_y'] = lineslog_frame.loc[in_idcs, 'y axis values'].values output_dict['in_ions'] = list( lineslog_frame.loc[in_idcs, 'latex_format'].values) # --- Outside limis if obj_data.h_gamma_valid == 'no': wave_idx = (lineslog_frame.lambda_theo < (obj_data.Wmin_Blue + spectral_limit)) | ( lineslog_frame.lambda_theo > (obj_data.Wmax_Red - spectral_limit)) out_idcs = Obs_Hindx & wave_idx output_dict['out_x'] = lineslog_frame.loc[out_idcs, 'x axis values'].values output_dict['out_y'] = lineslog_frame.loc[out_idcs, 'y axis values'].values output_dict['out_ions'] = list( lineslog_frame.loc[out_idcs, 'latex_format'].values) else: output_dict['out_x'] = None output_dict['out_y'] = None output_dict['out_ions'] = None return output_dict
def compare_RecombCoeffs(self, obj_data, lineslog_frame, spectral_limit = 200): #Load electron temperature and density (if not available it will use Te = 10000K and ne = 100cm^-3) T_e = obj_data.TeSIII if ~isnan(obj_data.TeSIII) else 10000.0 n_e = obj_data.neSII if ~isnan(obj_data.neSII) else 100.0 #Get the Hidrogen recombination lines that we have observed in this object Obs_Hindx = lineslog_frame.Ion.isin(self.RecombRatios_Ions) #Calculate recombination coefficients and reddening curve values Obs_H_Emis = empty(len(Obs_Hindx)) Obs_Ions = lineslog_frame.loc[Obs_Hindx, 'Ion'].values for i in range(len(Obs_Ions)): TransitionCode = Obs_Ions[i][Obs_Ions[i].find('_')+1:len(Obs_Ions[i])] Obs_H_Emis[i] = self.H1_atom.getEmissivity(tem = T_e, den = n_e, label = TransitionCode) #Normalize by Hbeta (this new constant is necessary to avoid a zero sigma) Hbeta_Emis = self.H1_atom.getEmissivity(tem = T_e, den = n_e, label = '4_2') Fbeta_flux = ufloat(lineslog_frame.loc['H1_4861A']['line_Flux'].nominal_value, lineslog_frame.loc['H1_4861A']['line_Flux'].std_dev) #Load theoretical and observational recombination ratios to data frame lineslog_frame.loc[Obs_Hindx,'line_Emissivity'] = Obs_H_Emis lineslog_frame.loc[Obs_Hindx,'line_TheoRecombRatio'] = Obs_H_Emis / Hbeta_Emis lineslog_frame.loc[Obs_Hindx,'line_ObsRecombRatio'] = lineslog_frame.loc[Obs_Hindx, 'line_Flux'].values / Fbeta_flux #Get indeces of emissions in each arm ObsBlue_Hindx = Obs_Hindx & (lineslog_frame.lambda_theo < obj_data.join_wavelength) ObsRed_Hindx = Obs_Hindx & (lineslog_frame.lambda_theo > obj_data.join_wavelength) #Recalculate red arm coefficients so they are normalized by red arm line (the most intense) if (ObsRed_Hindx.sum()) > 0: #Can only work if there is at least one line idx_Redmax = lineslog_frame.loc[ObsRed_Hindx]['flux_intg'].idxmax() #We do not use line_flux because it is a ufloat and it does not work with idxmax H_Redmax_flux = lineslog_frame.loc[idx_Redmax,'line_Flux'] H_Redmax_emis = lineslog_frame.loc[idx_Redmax,'line_Emissivity'] Flux_Redmax = ufloat(H_Redmax_flux.nominal_value * Hbeta_Emis / H_Redmax_emis, H_Redmax_flux.std_dev * Hbeta_Emis / H_Redmax_emis) lineslog_frame.loc[ObsRed_Hindx,'line_ObsRecombRatio'] = lineslog_frame.loc[ObsRed_Hindx, 'line_Flux'].values / Flux_Redmax #Load x axis values: (f_lambda - f_Hbeta) and y axis values: log(F/Fbeta)_theo - log(F/Fbeta)_obs to dataframe lineslog_frame.loc[Obs_Hindx,'x axis values'] = lineslog_frame.loc[Obs_Hindx, 'line_f'].values - lineslog_frame.loc['H1_4861A']['line_f'] lineslog_frame.loc[Obs_Hindx,'y axis values'] = unum_log10(lineslog_frame.loc[Obs_Hindx,'line_TheoRecombRatio'].values) - unum_log10(lineslog_frame.loc[Obs_Hindx,'line_ObsRecombRatio'].values) #Compute all the possible configuration of points and store them output_dict = {} #--- All points: output_dict['all_x'] = lineslog_frame.loc[Obs_Hindx,'x axis values'].values output_dict['all_y'] = lineslog_frame.loc[Obs_Hindx,'y axis values'].values output_dict['all_ions'] = list(lineslog_frame.loc[Obs_Hindx,'Ion'].values) #--- By arm output_dict['blue_x'] = lineslog_frame.loc[ObsBlue_Hindx,'x axis values'].values output_dict['blue_y'] = lineslog_frame.loc[ObsBlue_Hindx,'y axis values'].values output_dict['blue_ions'] = list(lineslog_frame.loc[ObsBlue_Hindx,'Ion'].values) output_dict['red_x'] = lineslog_frame.loc[ObsRed_Hindx,'x axis values'].values output_dict['red_y'] = lineslog_frame.loc[ObsRed_Hindx,'y axis values'].values output_dict['red_ions'] = list(lineslog_frame.loc[ObsRed_Hindx,'Ion'].values) #--- Inside limits if obj_data.h_gamma_valid == 'yes': in_idcs = Obs_Hindx elif obj_data.h_gamma_valid == 'no': wave_idx = ((lineslog_frame.lambda_theo > (obj_data.Wmin_Blue + spectral_limit)) & (lineslog_frame.lambda_theo < (obj_data.join_wavelength - spectral_limit))) \ | ((lineslog_frame.lambda_theo > (obj_data.join_wavelength + spectral_limit)) & (lineslog_frame.lambda_theo < (obj_data.Wmax_Red - spectral_limit))) in_idcs = Obs_Hindx & wave_idx output_dict['in_x'] = lineslog_frame.loc[in_idcs,'x axis values'].values output_dict['in_y'] = lineslog_frame.loc[in_idcs,'y axis values'].values output_dict['in_ions'] = list(lineslog_frame.loc[in_idcs,'Ion'].values) #--- Outside limis if obj_data.h_gamma_valid == 'no': wave_idx = (lineslog_frame.lambda_theo < (obj_data.Wmin_Blue + spectral_limit)) | (lineslog_frame.lambda_theo > (obj_data.Wmax_Red - spectral_limit)) out_idcs = Obs_Hindx & wave_idx output_dict['out_x'] = lineslog_frame.loc[out_idcs,'x axis values'].values output_dict['out_y'] = lineslog_frame.loc[out_idcs,'y axis values'].values output_dict['out_ions'] = list(lineslog_frame.loc[out_idcs,'Ion'].values) else: output_dict['out_x'] = None output_dict['out_y'] = None output_dict['out_ions'] = None return output_dict