Exemple #1
0
def test_bottom_bracket_logz():
    """Test for zinterp.bracket_logz()"""
    ZZsol = -1.98
    zmet1, zmet2 = bracket_logz(ZZsol)
    assert zmet1 == 1 and zmet2 == 2

    f1 = np.atleast_1d(2.)
    f2 = np.atleast_1d(4.)
    f = interp_logz(zmet1, zmet2, ZZsol, f1, f2)
    assert f[0] == f1[0]
Exemple #2
0
def test_high_bracket_logz():
    """Test for Z above grid."""
    # Test too high Z
    logZZsol = 0.2 + 0.01
    zmet1, zmet2 = bracket_logz(logZZsol)
    assert zmet1 == 21 and zmet2 == 22

    f1 = np.atleast_1d(2.)
    f2 = np.atleast_1d(4.)
    f = interp_logz(zmet1, zmet2, logZZsol, f1, f2)
    assert f[0] == f2[0]
Exemple #3
0
def interp_z_likelihood(args):
    """Generic single-pixel likeihood function where a single metallicity
    is linearly interpolated.

    Note that the SED can contain values of NaN, those bands will be
    automatically ignored from the likelihood calculation
    """
    global SP

    theta, theta_names, phi, phi_names, B, area, sed, err, sed_bands, \
        compute_bands = args

    meta1 = np.empty(5, dtype=float)
    meta2 = np.empty(5, dtype=float)

    band_indices = np.array([compute_bands.index(b) for b in sed_bands])

    # Evaluate the ln-likelihood function by interpolating between
    # metallicty bracket
    for name, val in itertools.chain(zip(theta_names, theta),
                                     zip(phi_names, phi)):
        if name == 'logmass':
            logm = val
        elif name == 'logZZsol':
            logZZsol = val
        elif name == 'logtau':
            SP.params['tau'] = 10. ** val
        elif name in SP.params.all_params:  # list of parameter names
            SP.params[name] = val

    zmet1, zmet2 = bracket_logz(logZZsol)
    # Compute fluxes with low metallicity
    SP.params['zmet'] = zmet1
    f1 = abs_ab_mag_to_micro_jy(
        SP.get_mags(tage=13.8, bands=compute_bands),
        phi[0])
    meta1[0] = SP.stellar_mass
    meta1[1] = SP.dust_mass
    meta1[2] = SP.log_lbol
    meta1[3] = SP.sfr
    meta1[4] = SP.log_age
    # Compute fluxes with high metallicity
    SP.params['zmet'] = zmet2
    f2 = abs_ab_mag_to_micro_jy(
        SP.get_mags(tage=13.8, bands=compute_bands),
        phi[0])
    meta2[0] = SP.stellar_mass
    meta2[1] = SP.dust_mass
    meta2[2] = SP.log_lbol
    meta2[3] = SP.sfr
    meta2[4] = SP.log_age

    # Interpolate and scale the SED by mass
    model_mjy = 10. ** logm * interp_logz(zmet1, zmet2, logZZsol, f1, f2)

    # Interpolate metadata between the two metallicities
    meta = interp_logz(zmet1, zmet2, logZZsol, meta1, meta2)

    # Compute likelihood
    # Automatically ignores pixels with no measurement (Nan)
    L = -0.5 * np.nansum(
        np.power((model_mjy[band_indices] + B * area - sed) / err, 2.))

    # Scale statistics by the total mass
    blob = {"logMstar": logm + np.log10(meta[0]),  # log solar masses,
            "logMdust": logm + np.log10(meta[1]),  # log solar masses
            "logLbol": logm * meta[2],  # log solar luminosities
            "logSFR": logm * meta[3],  # star formation rate, M_sun / yr
            "logAge": meta[4],
            "model_sed": model_mjy}  # note: background no included

    return L, blob
Exemple #4
0
    def __call__(self, theta):
        """Posterior likelihood call."""
        # Evaluate prior
        lnpriors = np.array([self._priors[n](v)
                             for n, v in zip(self._param_names, theta)])
        lnprior = np.sum(lnpriors)
        if ~np.isfinite(lnprior):
            model_mjy = np.empty(self.n_computed_bands, np.float)
            model_mjy.fill(np.nan)
            blob = {"lnpost": -np.inf,
                    "logMstar": np.nan,
                    "logMdust": np.nan,
                    "logLbol": np.nan,
                    "logSFR": np.nan,
                    "logAge": np.nan,
                    "model_sed": model_mjy,
                    "lnpriors": lnpriors}
            return -np.inf, blob

        meta1 = np.empty(5, dtype=float)
        meta2 = np.empty(5, dtype=float)

        for name, val in zip(self._param_names, theta):
            if name == 'logmass':
                logm = val
            elif name == 'logZZsol':
                logZZsol = val
            elif name == 'logtau':
                self.sp.params['tau'] = 10. ** val
            elif name in self.sp.params.all_params:  # list of parameter names
                self.sp.params[name] = val

        zmet1, zmet2 = bracket_logz(logZZsol)
        # Compute fluxes with low metallicity
        self.sp.params['zmet'] = zmet1
        f1 = abs_ab_mag_to_micro_jy(
            self.sp.get_mags(tage=13.8, bands=self._compute_bands),
            self.d)
        meta1[0] = self.sp.stellar_mass
        meta1[1] = self.sp.dust_mass
        meta1[2] = self.sp.log_lbol
        meta1[3] = self.sp.sfr
        meta1[4] = self.sp.log_age
        # Compute fluxes with high metallicity
        self.sp.params['zmet'] = zmet2
        f2 = abs_ab_mag_to_micro_jy(
            self.sp.get_mags(tage=13.8, bands=self._compute_bands),
            self.d)
        meta2[0] = self.sp.stellar_mass
        meta2[1] = self.sp.dust_mass
        meta2[2] = self.sp.log_lbol
        meta2[3] = self.sp.sfr
        meta2[4] = self.sp.log_age

        # Interpolate and scale the SED by mass
        model_mjy = 10. ** logm * interp_logz(zmet1, zmet2, logZZsol, f1, f2)

        # Interpolate metadata between the two metallicities
        meta = interp_logz(zmet1, zmet2, logZZsol, meta1, meta2)

        # Compute likelihood
        # Automatically ignores pixels with no measurement (Nan)
        lnL = -0.5 * np.nansum(
            np.power((model_mjy[self.band_indices]
                      - self._sed) / self._err, 2.))
        lnpost = lnprior + lnL
        if ~np.isfinite(lnpost):
            lnpost = -np.inf

        # Scale statistics by the total mass
        blob = {"lnpost": lnpost,
                "logMstar": logm + np.log10(meta[0]),  # log solar masses,
                "logMdust": logm + np.log10(meta[1]),  # log solar masses
                "logLbol": logm * meta[2],  # log solar luminosities
                "logSFR": logm * meta[3],  # star formation rate, M_sun / yr
                "logAge": meta[4],
                "model_sed": model_mjy,
                "lnpriors": lnpriors}

        return lnpost, blob
Exemple #5
0
def test_super_solar_bracket():
    """Test for bracket slightly above solar metallicity."""
    zmet1, zmet2 = bracket_logz(0.05)
    assert zmet1 == 20 and zmet2 == 21
Exemple #6
0
def test_top_bracket_logz():
    """Test for Z in top bracket"""
    zmet1, zmet2 = bracket_logz(0.20 - 0.01)
    assert zmet1 == 21 and zmet2 == 22
Exemple #7
0
def test_low_bracket_logz():
    """Test Z smaller than grid"""
    zmet1, zmet2 = bracket_logz(-2.0)
    assert zmet1 == 1 and zmet2 == 2