Ejemplo n.º 1
0
def optimize_region_residual(wl, residuals, sigma, mu):
    '''
    Determine the optimal parameters for the line kernels by fitting a Gaussian directly to the residuals.
    '''
    # Using sigma0, truncate the wavelength vector and residulas to include
    # only those portions that fall in the range [mu - sigma, mu + sigma]
    ind = (wl > mu - args.sigma0) & (wl < mu + args.sigma0)
    wl = wl[ind]
    R = residuals[ind]
    sigma = sigma[ind]

    sigma_mat = phi.sigAmp * sigma**2 * np.eye(len(wl))

    max_r = 6.0 * phi.l # [km/s]
    k_func = make_k_func(phi)

    # Use the full covariance matrix when doing the likelihood eval
    CC = get_dense_C(wl, k_func=k_func, max_r=max_r) + sigma_mat
    factor, flag = cho_factor(CC)
    logdet = np.sum(2 * np.log((np.diag(factor))))

    rr = C.c_kms/mu * np.abs(mu - wl) # Km/s

    def fprob(p):
        # The likelihood function

        # Requires sign about amplitude, so we can't use log.
        amp, sig = p

        gauss = amp * np.exp(-0.5 * rr**2/sig**2)

        r = R - gauss

        # Create a Gaussian using these parameters, and re-evaluate the residual
        lnprob = -0.5 * (np.dot(r, cho_solve((factor, flag), r)) + logdet)
        return lnprob

    par = Starfish.config["region_params"]
    p0 = np.array([10**par["logAmp"], par["sigma"]])

    f = lambda x: -fprob(x)

    try:
        p = fmin(f, p0, maxiter=10000, maxfun=10000, disp=False)
        # print(p)
        return p
    except np.linalg.linalg.LinAlgError:
        return p0
Ejemplo n.º 2
0
    def update_Phi(self, phi):
        self.logger.debug("Updating nuisance parameters to {}".format(phi))

        # Read off the Chebyshev parameters and update
        self.chebyshevSpectrum.update(phi.cheb)

        # Check to make sure the global covariance parameters make sense
        if phi.sigAmp < 0.1:
            raise C.ModelError("sigAmp shouldn't be lower than 0.1, something is wrong.")

        max_r = 6.0 * phi.l # [km/s]

        # Create a partial function which returns the proper element.
        k_func = make_k_func(phi)

        # Store the previous data matrix in case we want to revert later
        self.data_mat_last = self.data_mat
        self.data_mat = get_dense_C(self.wl, k_func=k_func, max_r=max_r) + phi.sigAmp*self.sigma_mat + self.region_mat
Ejemplo n.º 3
0
    def update_Phi(self, phi):
        self.logger.debug("Updating nuisance parameters to {}".format(phi))

        # Read off the Chebyshev parameters and update
        self.chebyshevSpectrum.update(phi.cheb)

        # Check to make sure the global covariance parameters make sense
        if phi.sigAmp < 0.1:
            raise C.ModelError("sigAmp shouldn't be lower than 0.1, something is wrong.")

        max_r = 6.0 * phi.l # [km/s]

        # Create a partial function which returns the proper element.
        k_func = make_k_func(phi)

        # Store the previous data matrix in case we want to revert later
        self.data_mat_last = self.data_mat
        self.data_mat = get_dense_C(self.wl, k_func=k_func, max_r=max_r) + phi.sigAmp*self.sigma_mat + self.region_mat
Ejemplo n.º 4
0
    def fprob(p):
        logAmp, sigma = p

        # set phi.regions = p
        phi.regions = np.array([logAmp, mu, sigma])[np.newaxis, :]

        max_rr = 4.0 * sigma
        max_r = max(max_rl, max_rr)

        k_func = make_k_func(phi)

        CC = get_dense_C(wl, k_func=k_func, max_r=max_r) + sigma_mat

        factor, flag = cho_factor(CC)
        logdet = np.sum(2 * np.log((np.diag(factor))))
        lnprob = -0.5 * (np.dot(R, cho_solve((factor, flag), R)) + logdet)

        # print(p, lnprob)
        return lnprob
Ejemplo n.º 5
0
    def update_nuisance(self, params):
        '''
        Update the nuisance parameters and data covariance matrix.

        :param params: large dictionary containing cheb, cov, and regions
        '''

        self.logger.debug("Updating nuisance parameters to {}".format(params))
        # Read off the Chebyshev parameters and update
        self.ChebyshevSpectrum.update(params["cheb"])

        # Create the full data covariance matrix.
        l = params["cov"]["l"]
        sigAmp = params["cov"]["sigAmp"]

        # Check to make sure the global covariance parameters make sense
        if sigAmp < 0.1:
            raise C.ModelError(
                "sigAmp shouldn't be lower than 0.1, something is wrong.")

        max_r = 6.0 * l  # [km/s]

        # Check all regions, take the max
        if self.nregions > 0:
            regions = params["regions"]
            keys = sorted(regions)
            sigmas = np.array([regions[key]["sigma"] for key in keys])  #km/s
            #mus = np.array([regions[key]["mu"] for key in keys])
            max_reg = 4.0 * np.max(sigmas)
            #If this is a larger distance than the global length, replace it
            max_r = max_reg if max_reg > max_r else max_r
            #print("Max_r now set by regions {}".format(max_r))

        # print("max_r is {}".format(max_r))

        # Create a partial function which returns the proper element.
        k_func = make_k_func(params)

        # Store the previous data matrix in case we want to revert later
        self.data_mat_last = self.data_mat
        self.data_mat = get_dense_C(self.wl, k_func=k_func,
                                    max_r=max_r) + sigAmp * self.sigma_matrix
Ejemplo n.º 6
0
    def update_Phi(self, p):
        self.logger.debug("Updating nuisance parameters to {}".format(p))

        # Read off the Chebyshev parameters and update
        ## May 1, 2017-- Turn off the Chebyshev spectrum for SpeX Prism mode.
        ## See Issue #13 in jammer:
        ## github.com/BrownDwarf/jammer/issues/13
        #self.chebyshevSpectrum.update(p.cheb)

        # Check to make sure the global covariance parameters make sense
        #if p.sigAmp < 0.1:
        #   raise C.ModelError("sigAmp shouldn't be lower than 0.1, something is wrong.")

        max_r = 6.0 * p.l # [km/s]

        # Create a partial function which returns the proper element.
        k_func = make_k_func(p)

        # Store the previous data matrix in case we want to revert later
        self.data_mat_last = self.data_mat
        self.data_mat = get_dense_C(self.wl, k_func=k_func, max_r=max_r) + p.sigAmp*self.sigma_mat
Ejemplo n.º 7
0
    def update_nuisance(self, params):
        '''
        Update the nuisance parameters and data covariance matrix.

        :param params: large dictionary containing cheb, cov, and regions
        '''

        self.logger.debug("Updating nuisance parameters to {}".format(params))
        # Read off the Chebyshev parameters and update
        self.ChebyshevSpectrum.update(params["cheb"])

        # Create the full data covariance matrix.
        l = params["cov"]["l"]
        sigAmp = params["cov"]["sigAmp"]

        # Check to make sure the global covariance parameters make sense
        if sigAmp < 0.1:
            raise C.ModelError("sigAmp shouldn't be lower than 0.1, something is wrong.")

        max_r = 6.0 * l # [km/s]

        # Check all regions, take the max
        if self.nregions > 0:
            regions = params["regions"]
            keys = sorted(regions)
            sigmas = np.array([regions[key]["sigma"] for key in keys]) #km/s
            #mus = np.array([regions[key]["mu"] for key in keys])
            max_reg = 4.0 * np.max(sigmas)
            #If this is a larger distance than the global length, replace it
            max_r = max_reg if max_reg > max_r else max_r
            #print("Max_r now set by regions {}".format(max_r))

        # print("max_r is {}".format(max_r))

        # Create a partial function which returns the proper element.
        k_func = make_k_func(params)

        # Store the previous data matrix in case we want to revert later
        self.data_mat_last = self.data_mat
        self.data_mat = get_dense_C(self.wl, k_func=k_func, max_r=max_r) + sigAmp*self.sigma_matrix
Ejemplo n.º 8
0
    sigma_mat = sigma**2 * np.eye(len(sigma))

    fname = Starfish.specfmt.format(spectrum_id, order) + "phi.json"
    phi = PhiParam.load(fname)

    if phi.regions is not None:
        region_func = make_k_func_region(phi)
        max_r = 4.0 * np.max(phi.regions, axis=0)[2]
        region_mat = get_dense_C(wl, k_func=region_func, max_r=max_r)
    else:
        region_mat = 0.0

    max_r = 6.0 * phi.l  # [km/s]
    # Create a partial function which returns the proper element.
    k_func = make_k_func(phi)

    data_mat = get_dense_C(wl, k_func=k_func,
                           max_r=max_r) + phi.sigAmp * sigma_mat + region_mat

    # Get many random draws from data_mat
    draws = random_draws(data_mat, num=4)
    min_spec, max_spec = std_envelope(draws)

if args.matplotlib:
    import matplotlib.pyplot as plt

    fig, ax = plt.subplots(nrows=2, figsize=(10, 8), sharex=True)

    ax[0].plot(wl, data, "b", label="data")
    ax[0].plot(wl, model, "r", label="model")
Ejemplo n.º 9
0
    sigma_mat =  sigma**2 * np.eye(len(sigma))

    fname = Starfish.specfmt.format(spectrum_id, order) + "phi.json"
    phi = PhiParam.load(fname)

    if phi.regions is not None:
        region_func = make_k_func_region(phi)
        max_r = 4.0 * np.max(phi.regions, axis=0)[2]
        region_mat = get_dense_C(wl, k_func=region_func, max_r=max_r)
    else:
        region_mat = 0.0

    max_r = 6.0 * phi.l # [km/s]
    # Create a partial function which returns the proper element.
    k_func = make_k_func(phi)

    data_mat = get_dense_C(wl, k_func=k_func, max_r=max_r) + phi.sigAmp*sigma_mat + region_mat

    # Get many random draws from data_mat
    draws = random_draws(data_mat, num=4)
    min_spec, max_spec = std_envelope(draws)


if args.matplotlib:
    import matplotlib.pyplot as plt

    fig, ax = plt.subplots(nrows=2, figsize=(10, 8), sharex=True)

    ax[0].plot(wl, data, "b", label="data")
    ax[0].plot(wl, model, "r", label="model")