예제 #1
0
resultsFolder = Path(obsConf['data_location']['results_folder'])

fileList = obsConf['data_location']['file_list']
objList = obsConf['data_location']['object_list']
z_list = obsConf['sample_data']['z_array']
norm_flux = obsConf['sample_data']['norm_flux']
percentil_array = obsConf['sample_data']['percentil_array']
voxel_grid_size = obsConf['sample_data']['grid_shape_array']

# Store emissivity ratios at standard conditions
H1 = pn.RecAtom('H', 1)
temp, den = 10000.0, 100.0

theoEmis_dict = {}
for chemLabel, plotLabel in label_Conver.items():
    ion, wave, latexLabel = sr.label_decomposition(chemLabel,
                                                   scalar_output=True)
    dict_label = f'{plotLabel}/Hdelta'
    theoRatio = H1.getEmissivity(temp, den, wave=wave) / H1.getEmissivity(
        temp, den, wave=4102)
    theoEmis_dict[dict_label] = theoRatio
red_model = sr.ExtinctionModel(Rv=obsConf['extinction']['R_v'],
                               red_curve=obsConf['extinction']['red_law'])

# Data location
objFolder = resultsFolder
db_address = objFolder / 'J0838_blue_database.fits'
linesMaps_fits_address = resultsFolder / f'J0838_lineParamMaps.fits'

# ----------------------------------------- Generate the image data
#
# # Empty containers for the images
예제 #2
0
        # Add missing rows
        S2_6716A_m_flux = objLinesDF.loc[
            'S2_6716A', 'obsFlux'] + objLinesDF.loc['S2_6731A', 'obsFlux']
        S2_6716A_m_err = np.sqrt(objLinesDF.loc['S2_6716A', 'obsFluxErr']**2 +
                                 objLinesDF.loc['S2_6731A', 'obsFluxErr']**2)
        S2_6716A_m_lambda = (objLinesDF.loc['S2_6716A', 'obsFlux'] +
                             objLinesDF.loc['S2_6731A', 'obsFlux']) / 2
        objLinesDF.loc['S2_6716A_m', 'obsFlux'] = S2_6716A_m_flux
        objLinesDF.loc['S2_6716A_m', 'obsFluxErr'] = S2_6716A_m_err
        objLinesDF.loc['S2_6716A_m', 'f_lambda'] = S2_6716A_m_lambda

        tableLines = sr_lineLabels.copy()
        i_6725A = sr_lineLabels.index('S2_6731A') + 1
        tableLines.insert(i_6725A, 'S2_6716A_m')

        ion_array, wave_array, latexLabel_array = sr.label_decomposition(
            tableLines, combined_dict=combined_line_dict)

        table_headers = [
            'Line ID', 'Observed flux',
            r'\makecell{Bayesian: \\ Direct method}',
            r'\makecell{\textsc{HII-CHI-mistry: } \\ Spherical}',
            r'\makecell{\textsc{HII-CHI-mistry: } \\ Plane-Parallel}',
            r'\makecell{Bayesian \textsc{HII-CHI-mistry: } \\ Plane-Parallel}',
            r'\makecell{Bayesian \\ Direct Method + \textsc{HII-CHI-mistry} \\ Plane-Parallel}'
        ]

        txt_headers = [
            'Observed_flux', 'Observed_err', 'DirectMethod_fitFlux',
            'DirectMethod_fitSigma', 'DirectMethod_difPercentage',
            'HIICHImistry_Spherical_fitFlux',
            'HIICHImistry_Spherical_fitSigma',
예제 #3
0
        cube_address_i = fitsFolder / fileList[i]
        mask_address = dataFolder / obsConf['data_location']['mask_global']
        db_address = objFolder / f'{obj}_database.fits'

        # Load the data
        wave, data, header = sr.import_fits_data(cube_address_i,
                                                 instrument='fits-cube',
                                                 frame_idx=0)
        mask_global_DF = sr.lineslogFile_to_DF(mask_address)

        # Declare voxels to analyse
        flux5007_image = fits.getdata(db_address,
                                      f'{ref_flux_line}_flux',
                                      ver=1)
        flux5007_levels = np.nanpercentile(flux5007_image, percentil_array)
        ion, wavelength, latexLabel = sr.label_decomposition(
            ref_flux_line, scalar_output=True)

        for idx_level, flux_level in enumerate(flux5007_levels):

            if idx_level + 1 < len(flux5007_levels):

                if idx_level == 0:
                    maFlux_image = np.ma.masked_where(
                        (flux5007_image >= flux5007_levels[idx_level + 1]),
                        flux5007_image)
                else:
                    maFlux_image = np.ma.masked_where(
                        (flux5007_image <= flux5007_levels[idx_level]) &
                        (flux5007_image >= flux5007_levels[idx_level + 1]),
                        flux5007_image)
예제 #4
0
model_variables = ['logOH', 'logU', 'logNO']
gw = sr.ModelGridWrapper()
grid_dict, axes_cords_a = gw.ndarray_from_DF(grid_3D_DF,
                                             axes_columns=model_variables)
grid_interpolators = gw.generate_xo_interpolators(grid_dict,
                                                  model_variables,
                                                  axes_cords_a,
                                                  interp_type='point')

exclude_lines = np.array(
    ['H1_4861A', 'N1_5198A', 'N1_5200A', 'C2_4267A', 'O2_4651A', 'C2_4659A'])
min_wavelength = 4700
input_lines = np.array(list(grid_dict.keys()))

ion_array, wave_array, latex_array = sr.label_decomposition(input_lines)
idcs_lines = ~np.isin(input_lines, exclude_lines) & (min_wavelength <
                                                     wave_array)
input_lines = input_lines[idcs_lines]

r_steps = 5
logOH_range = np.round(np.linspace(7.15, 9.0, r_steps), 3)
logU_range = np.round(np.linspace(-3.90, -1.40, r_steps), 3)
logNO_range = np.round(np.linspace(-1.90, -0.01, r_steps), 3)
i_step, n_steps = 0, logNO_range.size * logOH_range.size * logNO_range.size

# Loop throught the grid of synthetic conditions (around 30 seconds per fit)
objFolder = resultsFolder / f'CGCG007/'
# outputFits = objFolder / f'grid_logOH_logU_logNO.fits'
outputFits = objFolder / f'grid_logOH_logU_logNO_advi.fits'
    mainLinesLog = objFolder/f'{obj}_BR_linesLog.txt'

    mainLogDF = sr.lineslogFile_to_DF(mainLinesLog)

    flux_Hbeta, err_Hbeta = mainLogDF.loc['H1_4861A', 'intg_flux'], mainLogDF.loc['H1_4861A', 'intg_err']
    flux_norm = ufloat(flux_Hbeta, err_Hbeta)

    idcs_obsLines = ~mainLogDF.index.str.contains('_b')
    obsLines = mainLogDF.loc[idcs_obsLines].index.values

    linesFlux = mainLogDF.loc[idcs_obsLines, 'intg_flux'].values
    LinesErr = mainLogDF.loc[idcs_obsLines, 'intg_err'].values
    lineFluxArray = unumpy.uarray(linesFlux, LinesErr)
    lineNormArray = lineFluxArray/flux_norm

    ion_array, wave_array, latexLabel_array = sr.label_decomposition(obsLines, combined_dict=obsData['default_line_fitting'])

    # Plot Configuration
    defaultConf = STANDARD_PLOT.copy()
    rcParams.update(defaultConf)
    # plt.locator_params(axis='x', nbins=obsLines.size)

    x_loc = np.arange(obsLines.size)
    fig, ax = plt.subplots(figsize=(12, 8))
    ax.set_xticks(x_loc)
    ax.set_xticklabels(latexLabel_array, rotation=90)
    ax.errorbar(x_loc, unumpy.nominal_values(lineNormArray), yerr=unumpy.std_devs(lineNormArray), fmt='o', color='black',
                label='OSIRIS')

    # Loop through the extensions and put the data in the plot
    for ext in ['_B', '_R']:
예제 #6
0
    # First page has the default (primary) data
    new_hdul.append(fits.PrimaryHDU())

    # Second page for the fits file plot configuration
    col_waves = fits.Column(name='wave', array=wave, format='1E')
    hdu_table = fits.BinTableHDU.from_columns([col_waves], name='PlotConf')
    new_hdul.append(hdu_table)
    for key in coordinates_keys_list:
        new_hdul[1].header[key] = cube.data_header[key]
    new_hdul[1].header['NPIXWAVE'] = cube.data_header['NAXIS3']

    # Create flux maps for the main lines:
    for lineLabel, lineLimits in lineAreas.items():

        plot_image_file = objFolder/f'{obj}_{lineLabel}_contours.png'
        ion, wavelength, latexLabel = sr.label_decomposition(lineLabel, scalar_output=True)

        # Extract cube slice using mpdaf defult tools.
        # This requires the input wavelengths to be on the same scale as in the cube
        line_image = cube.get_image(np.array(lineLimits) * (1 + z_objs[i]), subtract_off=True)
        flux_image = line_image.data.data
        levelContours = np.nanpercentile(flux_image, pertil_array)

        # Store fluxes and contours
        hdu_image = fits.ImageHDU(name=f'{lineLabel}_flux', data=flux_image, ver=1)
        for idx, level in enumerate(levelContours):
            level_label = f'hierarch P{int(pertil_array[idx]*100)}'
            hdu_image.header[level_label] = level
        new_hdul.append(hdu_image)

        # Plot the image:
                                'Ne3': 7.065 + 0.15 * n_obj,
                                'Fe3': 5.055 + 0.15 * n_obj,
                                'Ar3': 5.725 + 0.15 * n_obj,
                                'Ar4': 5.065 + 0.15 * n_obj}

    # Declare lines to simulate
    merged_lines = {'O2_3726A_m': 'O2_3726A-O2_3729A', 'O2_7319A_m': 'O2_7319A-O2_7330A'}
    objParams['input_lines'] = ['H1_4341A', 'H1_4861A', 'H1_6563A', 'He1_4026A', 'He1_4471A', 'He1_5876A', 'He1_6678A', 'He1_7065A',
                   'He2_4686A', 'O2_3726A_m', 'O2_7319A_m', 'O3_4363A', 'O3_4959A', 'O3_5007A',
                   'N2_6548A', 'Ne3_3968A', 'Fe3_4658A', 'N2_6584A', 'S2_6716A', 'S2_6731A', 'S3_6312A', 'S3_9069A', 'S3_9531A', 'Ar3_7136A',
                   'Ar4_4740A']

    # We use the default lines database to generate the synthetic emission lines log for this simulation
    linesLogPath = os.path.join(sr._literatureDataFolder, sr._default_cfg['data_location']['lines_data_file'])

    ion_array, wavelength_array, latexLabel_array = sr.label_decomposition(objParams['input_lines'],
                                                                        combined_dict=merged_lines)

    # Define a pandas dataframe to contain the lines data
    linesLogHeaders = ['wavelength', 'intg_flux', 'intg_err', 'ion', 'blended_label', 'latexLabel']
    objLinesDF = pd.DataFrame(index=objParams['input_lines'], columns=linesLogHeaders)
    objLinesDF = objLinesDF.assign(wavelength=wavelength_array, ion=ion_array, latexLabel=latexLabel_array,
                                   blended_label='None')
    objLinesDF.sort_values(by=['wavelength'], ascending=True, inplace=True)

    # Blended labels
    idcs_blended = objLinesDF.index.isin(merged_lines.keys())
    objLinesDF.loc[idcs_blended, 'blended_label'] = list(merged_lines.values())

    # Declare extinction properties
    objRed = sr.ExtinctionModel(Rv=objParams['simulation_properties']['R_v'],
                                red_curve=objParams['simulation_properties']['reddenig_curve'],
예제 #8
0
        z_i = hdrs[1]["z"][0]

        lm = sr.LineMesurer(wave, flux, redshift=z_i, normFlux=normFlux)

        norm_spec = lm.continuum_remover(noiseRegionLims=noise_region)
        obsLinesTable = lm.line_finder(norm_spec, noiseWaveLim=noise_region, intLineThreshold=1)
        matchedDF = lm.match_lines(obsLinesTable, maskDF)
        # lm.plot_spectrum(obsLinesTable=obsLinesTable, matchedLinesDF=matchedDF, specLabel=f'Emission line detection')

        for line in linesForced:
            if line not in matchedDF.index:
                matchedDF.loc[line] = maskDF.loc[line]
        matchedDF.sort_values(by=['wavelength'], ascending=True, inplace=True)

        # Adding latex label to the plot
        ion_array, wavelength_array, latexLabel_array = sr.label_decomposition(matchedDF.index.values)
        matchedDF['latexLabel'] = latexLabel_array

        # Improve line region selection
        lm.plot_line_mask_selection(matchedDF, local_mask)

        # # Measure the emission lines
        # lm = sr.LineMesurer(wave, flux, redshift=z_i, normFlux=normFlux)
        # objMaskDF = sr.lineslogFile_to_DF(local_mask)
        # for i, lineLabel in enumerate(objMaskDF.index.values):
        #     wave_regions = objMaskDF.loc[lineLabel, 'w1':'w6'].values
        #     lm.fit_from_wavelengths(lineLabel, wave_regions)
        # lm.plot_line_grid(lm.linesDF)


# ------------------------------ Check available lines
예제 #9
0
    cube_address_i = dataFolder/fileList[i]
    objFolder = resultsFolder
    db_addresss = resultsFolder/f'{obj}_database.txt'

    # Load data
    obj_db = pd.read_csv(db_addresss, delim_whitespace=True, header=0, index_col=0)
    wave, cube, header = sr.import_fits_data(cube_address_i, instrument='MUSE')

    # Plot the line flux maps
    cube_shape = obsData['sample_data']['cube_size_array']
    for lineComp in obsData['default_line_fitting']['H1_6563A_b'].split('-'):
        for param in ['gauss_flux', 'mu', 'v_r', 'sigma', 'sigma_vel']:

            column_name = f'{lineComp}-{param}'
            lineFlux_i = np.reshape(obj_db[column_name].values, cube_shape.astype(int))
            ion, wave, latexCode = sr.label_decomposition(lineComp, scalar_output=True)

            # Define image countours based on the flux percentiles
            levelFlux_i = np.percentile(lineFlux_i[lineFlux_i > 0], pertil_array)
            levels_text_i = ['None'] * len(levelFlux_i)
            for idx, per in enumerate(pertil_array):
                levels_text_i[idx] = f'{levelFlux_i[idx]:.2f} $P_{{{per}}}$'

            # Crop image to the biggest square with non-nans
            nans = np.isnan(lineFlux_i)
            nancols = np.all(nans, axis=0)
            nanrows = np.all(nans, axis=1)
            firstcol = nancols.argmin()
            firstrow = nanrows.argmin()
            lastcol = len(nancols) - nancols[::-1].argmin()
            lastrow = len(nanrows) - nanrows[::-1].argmin()
예제 #10
0
gridLineDict, gridAxDict = sr.load_ionization_grid(log_scale=True)
lineInterpolator_dict = gridInterpolatorFunction(gridLineDict,
                                                 gridAxDict['logU'],
                                                 gridAxDict['Teff'],
                                                 gridAxDict['OH'],
                                                 interp_type='cube')

# Declare lines to simulate
lineLabels = np.array([
    'O2_3726A_m', 'He1_4471A', 'He2_4686A', 'O3_5007A', 'He1_5876A',
    'S2_6716A_m'
])
objParams['input_lines'] = lineLabels

# We use the default lines database to generate the synthetic emission lines log for this simulation
ion_array, wavelength_array, latexLabel_array = sr.label_decomposition(
    objParams['input_lines'])

# Define a pandas dataframe to contain the lines data
linesLogHeaders = [
    'wavelength', 'obsFlux', 'obsFluxErr', 'ion', 'blended_label', 'latexLabel'
]
objLinesDF = pd.DataFrame(index=lineLabels, columns=linesLogHeaders)
objLinesDF['ion'] = ion_array
objLinesDF['wavelength'] = wavelength_array
objLinesDF['latexLabel'] = latexLabel_array

# Declare extinction properties
objRed = sr.ExtinctionModel(
    Rv=objParams['simulation_properties']['R_v'],
    red_curve=objParams['simulation_properties']['reddenig_curve'],
    data_folder=objParams['data_location']['external_data_folder'])
예제 #11
0
        print(f'\n- {obj}')
        file_address_i = f'{dataFolder}/{fileList[i]}'
        wave, cube, header = sr.import_fits_data(file_address_i, instrument='MUSE')
        wave = wave / (1 + z_objs[i])
        print(f'\n-- {header["OBJECT"]}')

        # Get astronomical coordinates one pixel
        coord_sky = cube.wcs.pix2sky(idx_voxel, unit=u.deg)
        dec, ra = deg2sexa(coord_sky)[0]
        wcs_cube = WCS(cube.data_header)

        # Treat all the lines
        for lineLabel, lineLimits in lineAreas.items():

            # Get line flux region
            ion, lineWave, latexlabel = sr.label_decomposition([lineLabel])
            # lineIdcs = np.searchsorted(wave, np.array(lineLimits))
            # lineImage = cube[lineIdcs[0]:lineIdcs[1], :, :].sum(axis=0)/wave[lineIdcs[0]:lineIdcs[1]].size
            # print(lineLabel, wave[lineIdcs[0]:lineIdcs[1]].size)
            # flux_image = lineImage.data.data

            line_image = cube.get_image(np.array(lineLimits) * (1 + z_objs[i]), subtract_off=True)
            flux_image = line_image.data.data

            # Plot line image map with coordinates
            labelsDict = {'xlabel': r'RA',
                          'ylabel': r'DEC',
                          'title': r'Galaxy {} {}'.format(obj, latexlabel[0])}

            # Plot Configuration
            defaultConf = STANDARD_PLOT.copy()