Пример #1
0
def test_flux_conversion():

    # Create a dummy table that should get converted in a known way
    tab = Table()
    tab['DES_r'] = [20.]
    tab['DES_r_err'] = 0.5
    tab['VISTA_Y'] = 20.
    tab['VISTA_Y_err'] = 0.5

    fluxunits = 'mJy'

    fluxtab = convert_mags_to_flux(tab, fluxunits)

    # Check fluxes
    assert np.isclose(fluxtab['DES_r'],
                      0.036307805), "Check AB flux conversion."
    # WISE conversion is now done at the survey level
    #assert np.isclose(fluxtab['WISE_W1'], 0.0030954), "Check WISE flux conversion."
    assert np.isclose(fluxtab['VISTA_Y'],
                      0.0208732), "Check VISTA flux conversion."

    # Check errors
    assert np.isclose(fluxtab['DES_r_err'],
                      0.02123618797770558), "Check AB flux error."
    #assert np.isclose(fluxtab['WISE_W1_err'], 0.0018104783879441312), "Check WISE flux error."
    assert np.isclose(fluxtab['VISTA_Y_err'],
                      0.012208592584879318), "Check VISTA flux error."
Пример #2
0
Файл: cigale.py Проект: FRBs/FRB
def gen_cigale_in(photometry_table,
                  zcol,
                  idcol=None,
                  infile="cigale_in.fits",
                  overwrite=True,
                  **kwargs):
    """
    Generates the input catalog from
    a photometric catalog.

    Args:
        photometry_table (astropy Table):
            A table from some photometric
            catalog with magnitudes and
            error measurements. Currently supports
            DES, DECaLS, SDSS, Pan-STARRS and WISE

            The naming convention follows those specified in frb.galaxies.defs
            with the exception of WISE which use WISE-1, etc. although the code
            also handles WISE-W1, etc.
        zcol (str):
            Name of the column with redshift estimates
        idcol (str, optional):
            Name of the column with object IDs. By default,
            the code looks for the first column with "ID" in
            its name. If that's not present, it creates a
            column with row numbers for IDs.
        infile (str, optional):
            Output name + path for the CIGALE input file generated
        overwrite (bool, optional):
            If true, overwrites file if it already exists
        kwargs: only here to catch extras
    """
    #Table must have a column with redshift estimates
    if not isinstance(zcol, str):
        raise IOError("zcol must be a column name. i.e. a string")
    assert zcol in photometry_table.colnames, "{} not found in the table. Please check".format(
        zcol)

    magcols, mag_errcols = _detect_mag_cols(photometry_table)
    cigtab = photometry_table.copy()
    cigtab.rename_column(zcol, "redshift")
    photom_cols = magcols + mag_errcols

    # Rename any column with "ID" in it to "id"
    if idcol is None:
        try:
            idcol = [col for col in cigtab.colnames if "ID" in col.upper()][0]
        except IndexError:
            print("No column with 'ID' in name. Adding a column.")
            idcol = 'id'
            cigtab[idcol] = np.arange(len(cigtab)) + 1

    cigtab.rename_column(idcol, "id")

    #First round of renaming
    cigtab = convert_mags_to_flux(cigtab)
    cigtab = cigtab[['id', 'redshift'] + photom_cols]

    # Rename our filters to CIGALE names, as needed
    new_names = {
        'SDSS_u': 'sdss.up',
        'SDSS_g': 'sdss.gp',
        'SDSS_r': 'sdss.rp',
        'SDSS_i': 'sdss.ip',
        'SDSS_z': 'sdss.zp',
        'VLT_u': 'VLT_FORS2_u',
        'VLT_g': 'VLT_FORS2_g',
        'VLT_I': 'VLT_FORS2_I',
        'VLT_z': 'VLT_FORS2_z',
        'WISE_W1': 'WISE1',
        'WISE_W2': 'WISE2',
        'WISE_W3': 'WISE3',
        'WISE_W4': 'WISE4',
        'VISTA_Y': 'vista.vircam.Y',
        'VISTA_J': 'vista.vircam.J',
        'VISTA_H': 'vista.vircam.H',
        'VISTA_Ks': 'vista.vircam.Ks',
        'LRISr_I': 'LRIS_I',
        'LRISb_V': 'LRIS_V',
        'WFC3_F160W': 'hst.wfc3.F160W',
        'WFC3_F300X': 'WFC3_F300X',
        'Spitzer_3.6': 'spitzer.irac.ch1',
        'Spitzer_4.5': 'spitzer.irac.ch2',
        'NSC_g': 'DES_g',
        'NSC_r': 'DES_r',
        'NSC_i': 'DES_i',
        'NSC_z': 'DES_z',
        'NSC_Y': 'DES_Y',
        'DECam_r': 'DES_r'
    }
    for key in new_names:
        if key in photom_cols:
            cigtab.rename_column(key, new_names[key])
            # Try Error
            if key + '_err' in photom_cols:
                cigtab.rename_column(key + '_err', new_names[key] + '_err')

    cigtab.write(infile, overwrite=overwrite)
    return
Пример #3
0
def eazy_input_files(photom,
                     input_dir,
                     name,
                     out_dir,
                     prior_filter=None,
                     templates='eazy_v1.3',
                     combo="a",
                     cosmo=None,
                     magnitudes=False,
                     prior=_default_prior,
                     zmin=0.050,
                     zmax=7.000,
                     zstep=0.0010,
                     prior_ABZP=23.9,
                     n_min_col=5):
    """
    Write to disk a series of files needed to run EAZY
      - catalog file
      - translation file
      - param file

    Args:
        photom (dict):
            Held by an FRBGalaxy object
        input_dir (str):
            Path to eazy inputs/ folder  (can be relative)
            This is where eazy will be run
        name (str):
            Name of the source being analzyed
        out_dir (str):
            Path to eazy OUTPUT folder *relative* to the input_dir
        prior_filter (str, optional):
            If provided, use the flux in this filter for EAZY's prior
        templates (str, optional):
            Template set name to be used. Should be one of
            'br07_deafult','br07_goods','cww+kin','eazy_v1.0',
            'eazy_v1.1_lines','eazy_v1.2_dusty','eazy_v1.3','pegase',
            'pegase13'.
        combo (int or str, optional):
            Combinations of templates to be used for analysis. Can be
            one of 1,2,99,-1 and 'a'. Read EAZY's zphot.param.default
            file for details
        cosmo (astropy.cosmology, optional):
            Defaults to Planck15
        prior (str, optional):
            Name of the prior file found in the EAZY templates folder.
            Default value is 'prior_R_zmax7'.
        magnitudes (bool, optional):
            True if catalog contains magnitudes as opposed to F_nu values.
        zmin (float, optional):
            Minimum search redshift for EAZY. Default value is 0.05.
        zmax (float, optional):
            Maximum search redshift for EAZY. Be careful about the prior
            file not having information beyond a redshift less than zmax.
        zstep (float, optional):
            Step size of the redshift grid. (z_{i+1} = z_i+zstep*(1+z_i)).
            Default value is 0.001.
        prior_ABZP (float, optional):
            Zero point redshift for the band on which prior will be applied.
            Default value is for DECam r (https://cdcvs.fnal.gov/redmine/projects/des-sci-verification/wiki/Photometry)
    """
    #
    if cosmo is None:
        cosmo = Planck15

    # Output filenames
    catfile, param_file, translate_file = eazy_filenames(input_dir, name)

    # Check output dir
    full_out_dir = os.path.join(input_dir, out_dir)
    if not os.path.isdir(full_out_dir):
        warnings.warn(
            "Output directory {} does not exist, creating it!".format(
                full_out_dir))
        os.mkdir(full_out_dir)

    # Prior
    if prior_filter is not None:
        assert prior in _acceptable_priors, "Allowed priors are {}".format(
            _acceptable_priors)
        if prior_filter[-1] not in ['r', 'R', 'k', 'K']:
            raise IOError("Not prepared for this type of prior filter")

    # Test combo
    assert combo in _acceptable_combos, "Allowed values of 'combo' are {}".format(
        _acceptable_combos)

    # Generate the translate file
    filters = []
    codes = []
    for filt in photom.keys():
        if 'EBV' in filt:
            continue
        if 'err' in filt:
            ifilt = filt[:-4]
            pref = 'E'
        else:
            ifilt = filt
            pref = 'F'
        # Check
        if ifilt not in frb_to_eazy_filters.keys():
            warnings.warn(
                "Filter {} not in our set.  Add it to frb.galaxies.eazy.frb_to_eazy_filters"
                .format(ifilt))
            continue
        # Grab it
        code = '{}{}'.format(pref, frb_to_eazy_filters[ifilt])
        # Append
        filters.append(filt)
        codes.append(code)
    # Do it
    with open(translate_file, 'w') as f:
        for code, filt in zip(codes, filters):
            f.write('{} {} \n'.format(filt, code))
    print("Wrote: {}".format(translate_file))

    # Catalog file
    # Generate a simple table
    phot_tbl = Table()
    phot_tbl[filters[0]] = [photom[filters[0]]]
    for filt in filters[1:]:
        phot_tbl[filt] = photom[filt]
    # Convert --
    fluxtable = catalog_utils.convert_mags_to_flux(phot_tbl, fluxunits='uJy')
    # Write
    newfs, newv = [], []
    for key in fluxtable.keys():
        newfs.append(key)
        newv.append(str(fluxtable[key].data[0]))
    with open(catfile, 'w') as f:
        # Filters
        allf = ' '.join(newfs)
        f.write('# {} \n'.format(allf))
        # Values
        f.write(' '.join(newv))
    print("Wrote catalog file: {}".format(catfile))
    base_cat = os.path.basename(catfile)

    # Input file
    default_file = os.path.join(resource_filename('frb', 'data'), 'analysis',
                                'EAZY', 'zphot.param.default')
    #with open(default_file, 'r') as df:
    #    df_lines = df.readlines()
    in_tab = pandas.read_table(default_file,
                               delim_whitespace=True,
                               comment="#",
                               header=None,
                               names=('eazy_par', 'par_val'))

    # Expect it lands in src/ # Won't work if someone has put eazy in their bin folder.
    #_eazy_path = os.path.abspath(os.path.realpath(spawn.find_executable('eazy')))
    #_eazy_root = _eazy_path[0:_eazy_path.find('src')]

    # Change default parameters to reflect current values
    in_tab.par_val[in_tab.eazy_par == 'FILTERS_RES'] = os.path.join(
        resource_filename('frb', 'data'), 'analysis', 'EAZY',
        'FILTER.RES.latest')
    in_tab.par_val[in_tab.eazy_par == 'TEMPLATES_FILE'] = os.path.join(
        _eazy_root, 'templates/' + templates + ".spectra.param")
    in_tab.par_val[in_tab.eazy_par == 'TEMP_ERR_FILE'] = os.path.join(
        _eazy_root, 'templates/TEMPLATE_ERROR.eazy_v1.0')
    in_tab.par_val[in_tab.eazy_par == 'TEMPLATE_COMBOS'] = combo
    in_tab.par_val[in_tab.eazy_par == 'WAVELENGTH_FILE'] = os.path.join(
        _eazy_root, 'templates/EAZY_v1.1_lines/lambda_v1.1.def')
    in_tab.par_val[in_tab.eazy_par == 'LAF_FILE'] = os.path.join(
        _eazy_root, 'templates/LAFcoeff.txt')
    in_tab.par_val[in_tab.eazy_par == 'DLA_FILE'] = os.path.join(
        _eazy_root, 'templates/DLAcoeff.txt')
    in_tab.par_val[in_tab.eazy_par == 'CATALOG_FILE'] = base_cat
    if magnitudes:
        in_tab.par_val[in_tab.eazy_par == 'MAGNITUDES'] = 'y'
    else:
        in_tab.par_val[in_tab.eazy_par == 'MAGNITUDES'] = 'n'
    in_tab.par_val[in_tab.eazy_par == 'N_MIN_COLORS'] = n_min_col
    in_tab.par_val[in_tab.eazy_par == 'OUTPUT_DIRECTORY'] = out_dir
    # Prior
    if prior_filter is not None:
        in_tab.par_val[in_tab.eazy_par == 'APPLY_PRIOR'] = 'y'
        in_tab.par_val[in_tab.eazy_par == 'PRIOR_FILE'] = os.path.join(
            _eazy_root, 'templates/' + prior + '.dat')
        in_tab.par_val[in_tab.eazy_par == 'PRIOR_FILTER'] = str(
            frb_to_eazy_filters[prior_filter])
        in_tab.par_val[in_tab.eazy_par == 'PRIOR_ABZP'] = prior_ABZP
    in_tab.par_val[in_tab.eazy_par == 'Z_MIN'] = zmin
    in_tab.par_val[in_tab.eazy_par == 'Z_MAX'] = zmax
    in_tab.par_val[in_tab.eazy_par == 'Z_STEP'] = zstep
    in_tab.par_val[in_tab.eazy_par == 'H0'] = cosmo.H0.value
    in_tab.par_val[in_tab.eazy_par == 'OMEGA_M'] = cosmo.Om0
    in_tab.par_val[in_tab.eazy_par == 'OMEGA_L'] = cosmo.Ode0

    # Create infile
    in_tab.to_csv(param_file, header=False, index=False, sep="\t")

    #    with open(param_file, 'w') as f:
    #        for dfline in df_lines:
    #            if 'CATALOG_FILE' in dfline:
    #                line = dfline.replace('REPLACE.cat', base_cat)
    #            elif prior_filter is not None and 'APPLY_PRIOR' in dfline:
    #                line = dfline.replace('n', 'y', 1)
    #            elif prior_filter is not None and 'PRIOR_FILTER' in dfline:
    #                line = dfline.replace('999', str(frb_to_eazy_filters[prior_filter]), 1)
    #            elif prior_filter is not None and 'PRIOR_FILE' in dfline:
    #                line = dfline  # Deal with this if we do anything other than r
    #            elif prior_filter is not None and 'PRIOR_ABZP' in dfline:
    #                line = dfline  # Deal with this if we do anything other than r
    #            elif 'Directory to put output files in' in dfline:  # Relative to the Input directory
    #                line = dfline[0:10]+dfline[10:].replace('OUTPUT', out_dir, -1)
    #            else:
    #                line = dfline
    # Write
    #            f.write(line)
    #    print("Wrote param file: {}".format(param_file))

    # Generate a soft link to the templates
    template_folder = os.path.join(_eazy_root, 'templates')
    link = os.path.join(input_dir, '..', 'templates')
    if not os.path.isdir(link):
        os.symlink(template_folder, link)
    return
Пример #4
0
    def parse_photom(self,
                     phot_tbl,
                     max_off=1 * units.arcsec,
                     overwrite=True,
                     EBV=None):
        """
        Parse photometry from an input table

        Fills the self.photom dict

        Also fills fluxes in mJy

        Args:
            phot_tbl (astropy.table.Table):
                ra, dec entires are required
            max_off (Angle, optional):
            overwrite (bool, optional):
            EBV (float, optional):  Galactic reddening.  If included, the photometry
               has been corrected for this.  If not, who knows?!  :)

        Returns:

        """
        phot_coord = SkyCoord(ra=phot_tbl['ra'],
                              dec=phot_tbl['dec'],
                              unit='deg')
        sep = self.coord.separation(phot_coord)
        row = np.argmin(sep)
        # Satisfy minimum offset?
        if sep[row] > max_off:
            print("No photometric sources within {} of the galaxy".format(
                max_off))
            return
        # Get a flux table
        flux_tbl = convert_mags_to_flux(phot_tbl, fluxunits='mJy')

        # Fill fluxes (mJy)
        for filter in defs.valid_filters:
            # Value
            if filter in phot_tbl.keys():
                if (filter in self.photom.keys()) and (not overwrite):
                    pass
                else:
                    # -999. is used as empty fill value
                    if phot_tbl[filter][row] < -990:
                        pass
                    else:
                        self.photom[filter] = phot_tbl[filter][row]
                        self.photom[filter + '_flux'] = flux_tbl[filter][row]
                        # Try error
                        if filter + '_err' in phot_tbl.keys():
                            self.photom[filter +
                                        '_err'] = phot_tbl[filter +
                                                           '_err'][row]
                            self.photom[filter +
                                        '_flux_err'] = flux_tbl[filter +
                                                                '_err'][row]
                        # Try reference
                        if filter + '_ref' in phot_tbl.keys():
                            self.photom[filter +
                                        '_ref'] = phot_tbl[filter +
                                                           '_ref'][row]

                        # Add entries for corresponding flux values.
        # EBV
        if EBV is not None:
            self.photom['EBV'] = EBV