Exemplo n.º 1
0
def skew_gaussian(peak, sig_minus, sig_plus):
    """
    Creates a skewed gaussian
    """
    x = np.arange(-100, 100, .01)
    g1 = Gaussian1D(amplitude=peak, stddev=sig_minus)(x)
    g2 = Gaussian1D(amplitude=peak, stddev=sig_plus)(x)

    ind = np.argmin(abs(x))
    g3 = np.copy(g1)
    g3[ind:] = g2[ind:]
    gauss = np.array([x, g3])
    return gauss
Exemplo n.º 2
0
def test_subpixel_gauss_1D():
    """
    Test subpixel accuracy of the integrate mode with gaussian 1D model.
    """
    gauss_1D = Gaussian1D(1, 0, 0.1)
    values = discretize_model(gauss_1D, (-1, 2), mode='integrate', factor=100)
    assert_allclose(values.sum(), np.sqrt(2 * np.pi) * 0.1, atol=0.00001)
Exemplo n.º 3
0
    def add_emission_line(self, line_center, line_width, line_amp,
                          line_type="gaussian"):
        """
        Add an emission line to this spectrum.

        Parameters
        ----------
        line_center : float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The line center position in units of keV, in the observer frame.
        line_width : one or more float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The line width (FWHM) in units of keV, in the observer frame. Can also
            input the line width in units of velocity in the rest frame. For the Voigt
            profile, a list, tuple, or array of two values should be provided since there
            are two line widths, the Lorentzian and the Gaussian (in that order).
        line_amp : float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The integrated line amplitude in the units of the flux 
        line_type : string, optional
            The line profile type. Default: "gaussian"
        """
        line_center = parse_value(line_center, "keV")
        line_width = parse_value(line_width, "keV", equivalence=line_width_equiv(line_center))
        line_amp = parse_value(line_amp, self._units)
        if line_type == "gaussian":
            sigma = line_width / sigma_to_fwhm
            line_amp /= sqrt2pi * sigma
            f = Gaussian1D(line_amp, line_center, sigma)
        else:
            raise NotImplementedError("Line profile type '%s' " % line_type +
                                      "not implemented!")
        self.flux += u.Quantity(f(self.emid.value), self._units)
        self._compute_total_flux()
Exemplo n.º 4
0
    def add_absorption_line(self, line_center, line_width, equiv_width, 
                            line_type='gaussian'):
        """
        Add an absorption line to this spectrum.

        Parameters
        ----------
        line_center : float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The line center position in units of keV, in the observer frame.
        line_width : one or more float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The line width (FWHM) in units of keV, in the observer frame. Can also
            input the line width in units of velocity in the rest frame. For the Voigt
            profile, a list, tuple, or array of two values should be provided since there
            are two line widths, the Lorentzian and the Gaussian (in that order).
        equiv_width : float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The equivalent width of the line, in units of milli-Angstrom
        line_type : string, optional
            The line profile type. Default: "gaussian"
        """
        line_center = parse_value(line_center, "keV")
        line_width = parse_value(line_width, "keV", equivalence=line_width_equiv(line_center))
        equiv_width = parse_value(equiv_width, "1.0e-3*angstrom") # in milliangstroms
        equiv_width *= 1.0e-3 # convert to angstroms
        if line_type == "gaussian":
            sigma = line_width / sigma_to_fwhm
            B = equiv_width*line_center*line_center
            B /= hc * sqrt2pi * sigma
            f = Gaussian1D(B, line_center, sigma)
        else:
            raise NotImplementedError("Line profile type '%s' " % line_type +
                                      "not implemented!")
        self.flux *= np.exp(-f(self.emid.value))
        self._compute_total_flux()
Exemplo n.º 5
0
def Gfit2hist(data):
    ''' Gaussian fit to the frequency distribution of the nddata.
    '''
    freq = itemfreq(data.flatten())
    fitter = LevMarLSQFitter()
    mode = freq[freq[:, 1] == freq[:, 1].max(), 0][0]
    init = Gaussian1D(mean=mode)
    fitG = fitter(init, freq[:, 0], freq[:, 1])
    return fitG
Exemplo n.º 6
0
    def add_slices(self, xcen, xshift, xspan, psf_xlength, wmin, wmax, wmin_d,
                   wmax_d):

        xcens = range(xcen - xshift, xcen + xshift, xspan)
        for c, t in zip(xcens[1:], self.psf.traces):
            _, _, sl_msignal = self.add_slice(t, c, wmin, wmax, wmin_d, wmax_d)

            self.mod_init.append(
                Gaussian1D(amplitude=sl_msignal, mean=c, stddev=psf_xlength))
            self.sl_cen.append(c)
Exemplo n.º 7
0
def test_gaussian_eval_1D(mode):
    """
    Discretize Gaussian with different modes and check
    if result is at least similar to Gaussian1D.eval().
    """
    model = Gaussian1D(1, 0, 20)
    x = np.arange(-100, 101)
    values = model(x)
    disc_values = discretize_model(model, (-100, 101), mode=mode)
    assert_allclose(values, disc_values, atol=0.001)
Exemplo n.º 8
0
    def get_mask(self,
                 flt_name,
                 kernel_fwhm=1.25,
                 background_box=20,
                 thr=0.05,
                 npixels=100):
        """
        Function to create a mask (set to 0 for no detection and 1 for detection) appropriate to mask WFC3 slitless data. 
        Attributes
        ----------
        flt_name string containing the name of the FLT name to create a mask for
        kernel_fwhm Float The size of the detection kernel (default = 1.25 pixel)
        background_box Int The saie fo the background box when estimating the background (default = 20 pixels) 
        thr Float Threshold above noise to detect signal (default = 0.25)
        npixels Int number of pixels for a spectrum to be detected (default = 15)    

        Output
        ------
        A numpy array containing the mask
        """
        h = fits.open(flt_name)[0].header
        filt = h["FILTER"]

        fin = fits.open(flt_name)
        image = fin["SCI"].data
        err = fin["ERR"].data

        dq = fin["DQ"].data
        dq = np.bitwise_and(dq,
                            np.zeros(np.shape(dq), np.int16) + self.bit_mask)

        g = Gaussian1D(mean=0., stddev=kernel_fwhm / 2.35)
        x = np.arange(16.) - 8
        a = g(x)
        kernel = np.tile(a, (16 * int(kernel_fwhm + 1), 1)).T
        kernel = kernel / np.sum(kernel)

        b = Background2D(image, background_box)

        image = image - b.background
        threshold = thr * err

        image[dq > 0] = 0.  #np.nan

        mask = detect_sources(image,
                              threshold,
                              npixels=npixels,
                              filter_kernel=kernel).data

        ok = (mask == 0.) & (dq == 0)
        mask[~ok] = 1.

        return mask
Exemplo n.º 9
0
def lnprob(p, n, N):

    x = np.linspace(0, 170, 10000)
    G = Gaussian1D(1, 0, p)(x)
    use = x < 15.9  #sb radius
    theta = simps(abs(x[use]) * G[use], x[use]) / simps(abs(x) * G, x)

    bounds = (0, 100)
    lp = lnprior(p, bounds)
    if not np.isfinite(lp):
        return -np.inf

    ll = lnlike(theta, n, N)
    if np.isnan(ll): return -np.inf
    return ll + lp
Exemplo n.º 10
0
def test3():
    from astropy.modeling.functional_models import Gaussian1D

    def norm_gauss(sigma):
        return 1 / np.sqrt(2 * np.pi * sigma**2)

    x = np.arange(-8, 8, 0.1)

    ax1 = plt.subplot(1, 1, 1)
    for s in range(1, 5):
        gauss = Gaussian1D(amplitude=1, mean=0, stddev=s)
        ax1.plot(x,
                 norm_gauss(s) * gauss(x),
                 ls=":",
                 label="sigma={0:.0f}, HWHM={1:.1f}".format(s, 2.355 * s / 2))
        ax1.plot(x,
                 gauss(x),
                 label="sigma={0:.0f}, HWHM={1:.1f}".format(s, 2.355 * s / 2))
Exemplo n.º 11
0

# %%
def fisher(pdf_grid, dx):
    normed = pdf_grid / np.trapz(pdf_grid, dx=dx)

    grad = np.gradient(normed, dx)

    return np.trapz(grad ** 2 / normed, dx=dx)


# %%
mi, ma, s = -30, 30, 1001
xs = np.linspace(mi, ma, s)
dx = (ma - mi) / s
pdf = Gaussian1D(stddev=1)(xs)
pdf /= np.trapz(pdf, dx=dx)

print(np.trapz(pdf, dx=dx))
print(np.sum(pdf))

# %%
mi, ma, s = -30, 30, 1001
xs = np.linspace(mi, ma, s)
dx = (ma - mi) / s

pdf = Gaussian1D(stddev=1)(xs)
pdf /= np.trapz(pdf, dx=dx)

plt.figure()
plt.plot(xs, pdf)
Exemplo n.º 12
0
    def __init__(
        self,
        obs_x,
        obs_y,
        estimate_start=False,
        param_info=None,
        filename=None,
        tformat=None,
    ):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.
        """
        # check that param_info or filename is set
        if filename is None and param_info is None:
            raise ValueError("Either param_info or filename need to be set \
                             when initializing a PAHFITBase object")

        # read in the parameter info from a file
        if filename is not None:
            param_info = self.read(filename, tformat=tformat)

        if estimate_start:
            # guess values and update starting point (if not set fixed) based on the input spectrum
            param_info = self.estimate_init(obs_x, obs_y, param_info)

        if not param_info:
            raise ValueError("No parameter information set.")

        self.param_info = param_info

        bb_info = param_info[0]
        dust_features = param_info[1]
        h2_features = param_info[2]
        ion_features = param_info[3]
        att_info = param_info[4]

        # setup the model
        self.model = None
        self.bb_info = bb_info
        if bb_info is not None:
            bbs = []
            for k in range(len(bb_info["names"])):
                BBClass = ModifiedBlackBody1D if bb_info["modified"][
                    k] else BlackBody1D
                bbs.append(
                    BBClass(
                        name=bb_info["names"][k],
                        temperature=bb_info["temps"][k],
                        amplitude=bb_info["amps"][k],
                        bounds={
                            "temperature": bb_info["temps_limits"][k],
                            "amplitude": bb_info["amps_limits"][k],
                        },
                        fixed={
                            "temperature": bb_info["temps_fixed"][k],
                            "amplitude": bb_info["amps_fixed"][k],
                        },
                    ))
            self.model = sum(bbs[1:], bbs[0])

        self.dust_features = dust_features
        if dust_features is not None:
            df = []
            for k in range(len(dust_features["names"])):
                df.append(
                    Drude1D(
                        name=dust_features["names"][k],
                        amplitude=dust_features["amps"][k],
                        x_0=dust_features["x_0"][k],
                        fwhm=dust_features["fwhms"][k],
                        bounds={
                            "amplitude": dust_features["amps_limits"][k],
                            "x_0": dust_features["x_0_limits"][k],
                            "fwhm": dust_features["fwhms_limits"][k],
                        },
                        fixed={
                            "amplitude": dust_features["amps_fixed"][k],
                            "x_0": dust_features["x_0_fixed"][k],
                            "fwhm": dust_features["fwhms_fixed"][k],
                        },
                    ))

            df = sum(df[1:], df[0])
            if self.model:
                self.model += df
            else:
                self.model = df

        self.h2_features = h2_features
        if h2_features is not None:
            h2 = []
            for k in range(len(h2_features["names"])):
                h2.append(
                    Gaussian1D(
                        name=h2_features["names"][k],
                        amplitude=h2_features["amps"][k],
                        mean=h2_features["x_0"][k],
                        stddev=h2_features["fwhms"][k] / 2.355,
                        bounds={
                            "amplitude":
                            h2_features["amps_limits"][k],
                            "mean":
                            h2_features["x_0_limits"][k],
                            "stddev": (
                                h2_features["fwhms"][k] * 0.9 / 2.355,
                                h2_features["fwhms"][k] * 1.1 / 2.355,
                            ),
                        },
                        fixed={
                            "amplitude": h2_features["amps_fixed"][k],
                            "mean": h2_features["x_0_fixed"][k],
                            "stddev": h2_features["fwhms_fixed"][k],
                        },
                    ))
            h2 = sum(h2[1:], h2[0])
            if self.model:
                self.model += h2
            else:
                self.model = h2

        self.ion_features = ion_features
        if ion_features is not None:
            ions = []
            for k in range(len(ion_features["names"])):
                ions.append(
                    Gaussian1D(
                        name=ion_features["names"][k],
                        amplitude=ion_features["amps"][k],
                        mean=ion_features["x_0"][k],
                        stddev=ion_features["fwhms"][k] / 2.355,
                        bounds={
                            "amplitude":
                            ion_features["amps_limits"][k],
                            "mean":
                            ion_features["x_0_limits"][k],
                            "stddev": (
                                ion_features["fwhms"][k] * 0.9 / 2.355,
                                ion_features["fwhms"][k] * 1.1 / 2.355,
                            ),
                        },
                        fixed={
                            "amplitude": ion_features["amps_fixed"][k],
                            "mean": ion_features["x_0_fixed"][k],
                            "stddev": ion_features["fwhms_fixed"][k],
                        },
                    ))
            ions = sum(ions[1:], ions[0])
            if self.model:
                self.model += ions
            else:
                self.model = ions

        # add additional att components to the model if necessary
        if not self.model:
            raise ValueError("No model components found")

        self.att_info = att_info
        if att_info is not None:
            for k in range(len(att_info["names"])):
                if (
                        att_info["names"][k] == "S07_att"
                ):  # Only loop through att components that can be parameterized
                    self.model *= S07_attenuation(
                        name=att_info["names"][k],
                        tau_sil=att_info["amps"][k],
                        bounds={"tau_sil": att_info["amps_limits"][k]},
                        fixed={"tau_sil": att_info["amps_fixed"][k]},
                    )
                else:
                    self.model *= att_Drude1D(
                        name=att_info["names"][k],
                        tau=att_info["amps"][k],
                        x_0=att_info["x_0"][k],
                        fwhm=att_info["fwhms"][k],
                        bounds={
                            "tau": att_info["amps_limits"][k],
                            "fwhm": att_info["fwhms_limits"][k],
                        },
                        fixed={"x_0": att_info["x_0_fixed"][k]},
                    )
Exemplo n.º 13
0
    return G(power) / (width * np.sqrt(np.pi) * G(power - 1 / 2))


def HWHM_moffat(width, power):
    return width * np.sqrt(2**(1 / power) - 1)


x = np.arange(0, 10, 0.1)
sigma = np.array([1, 2])
width = np.array([2, 5])
power = np.array([1.5, 2.5])

ax1 = plt.subplot(1, 2, 1)
ax2 = plt.subplot(1, 2, 2)
for s in sigma:
    gauss = Gaussian1D(amplitude=1, mean=0, stddev=s)
    ax1.plot(x,
             norm_gauss(s) * gauss(x),
             ls=":",
             label="sigma={0:.0f}, HWHM={1:.1f}".format(s, 2.355 * s / 2))
    ax2.plot(x,
             -2.5 * np.log10(norm_gauss(s) * gauss(x)),
             ls=":",
             label="sigma={0:.0f}, HWHM={1:.1f}".format(s, 2.355 * s / 2))

for w in width:
    for p in power:
        moffat = Moffat1D(amplitude=1, x_0=0, gamma=w, alpha=p)
        HWHM = HWHM_moffat(w, p)
        ax1.plot(x,
                 norm_moffat(w, p) * moffat(x),
Exemplo n.º 14
0
def eqws(comp_type, x_0, amp, fwhm_stddev, obs_fit):
    """
    Calculate the emission features equivalent width
    (integral[(I_nu-I_cont)/I_cont d_lam]) in microns.

    Parameters
    ----------
    comp_type : string
        type of emission component (Drude1D/Gaussian)
    x_0 : float
        central wavelength of the feature.
    amp : float
        central intensity of the feature.
    fwhm_stddev : float
        fwhm or stddev of the feature depending on comp_type.
    Returns
    -------
    eqw : float
        the equivalent width of the feature
    """
    # Check if the emission component is Gaussian and calculate fwhm.
    if comp_type == 'Gaussian1D':
        fwhm = 2 * fwhm_stddev * np.sqrt(2 * np.log(2))
    else:
        fwhm = fwhm_stddev

    # Get range and wavelength region for integration.
    low = x_0 - (fwhm * 6)
    lmin = low if low > 0 else 0.
    lmax = x_0 + (fwhm * 6)
    # lam = np.arange(100) / 99 * (lmax - lmin) + lmin
    lam = np.linspace(lmin, lmax, num=100)

    # Calculate the continuum and feature components in the integration range.
    cont_components = []
    for cmodel in obs_fit:
        if isinstance(cmodel, BlackBody1D):
            cont_components.append(cmodel)
    cont_model = cont_components[0]
    for cmodel in cont_components[1:]:
        cont_model += cmodel
    continuum = np.nan_to_num(cont_model(lam))

    if comp_type == 'Drude1D':
        drude = Drude1D(amplitude=amp,
                        x_0=x_0,
                        fwhm=fwhm)
        lnu = drude(lam)

    elif comp_type == 'Gaussian1D':
        gauss = Gaussian1D(amplitude=amp,
                           mean=x_0,
                           stddev=fwhm_stddev)
        lnu = gauss(lam)

    # Following the EQW calculation in IDL PAHFIT, we define a default broad limit (bl).
    # Set bl to replace the continuum in the EQW calculation
    # by its profile-averaged value for fractional FWHM greater than that limit.
    # Useful when the EQW requires extrapolation to regions where the continuum
    # can vanish, such that f_line/f_continuum diverges.
    # Default value bl = 0.05.
    bl = 0.05

    # Calculate EQW.
    if fwhm / x_0 > bl:
        ilam = integrate.simpson(lnu, lam)
        weighted_cont = integrate.simpson(lnu * continuum, lam) / ilam
        eqw = ilam / weighted_cont
    else:
        eqw = integrate.simpson(lnu / continuum, lam)

    return eqw
Exemplo n.º 15
0
    def __init__(self, param_info=None, filename=None, tformat=None):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.
        """
        # check that param_info or filename is set
        if filename is None and param_info is None:
            raise ValueError('Either param_info or filename need to be set \
                             when initializing a PAHFITBase object')

        # read in the parameter info from a file
        if filename is not None:
            param_info = self.read(filename, tformat=tformat)

        bb_info = param_info[0]
        dust_features = param_info[1]
        h2_features = param_info[2]
        ion_features = param_info[3]
        att_info = param_info[4]

        # setup the model
        self.bb_info = bb_info
        if bb_info is not None:
            # 1st component defines the overall model variable
            self.model = BlackBody1D(name=bb_info['names'][0],
                                     temperature=bb_info['temps'][0],
                                     amplitude=bb_info['amps'][0],
                                     bounds={
                                         'temperature':
                                         bb_info['temps_limits'][0],
                                         'amplitude': bb_info['amps_limits'][0]
                                     },
                                     fixed={
                                         'temperature':
                                         bb_info['temps_fixed'][0],
                                         'amplitude': bb_info['amps_fixed'][0]
                                     })
            for k in range(1, len(bb_info['names'])):
                self.model += BlackBody1D(name=bb_info['names'][k],
                                          temperature=bb_info['temps'][k],
                                          amplitude=bb_info['amps'][k],
                                          bounds={
                                              'temperature':
                                              bb_info['temps_limits'][k],
                                              'amplitude':
                                              bb_info['amps_limits'][k]
                                          },
                                          fixed={
                                              'temperature':
                                              bb_info['temps_fixed'][k],
                                              'amplitude':
                                              bb_info['amps_fixed'][k]
                                          })

        self.dust_features = dust_features
        if dust_features is not None:
            for k in range(len(dust_features['names'])):
                self.model += Drude1D(name=dust_features['names'][k],
                                      amplitude=dust_features['amps'][k],
                                      x_0=dust_features['x_0'][k],
                                      fwhm=dust_features['fwhms'][k],
                                      bounds={
                                          'amplitude':
                                          dust_features['amps_limits'][k],
                                          'x_0':
                                          dust_features['x_0_limits'][k],
                                          'fwhm':
                                          dust_features['fwhms_limits'][k]
                                      },
                                      fixed={
                                          'amplitude':
                                          dust_features['amps_fixed'][k],
                                          'x_0':
                                          dust_features['x_0_fixed'][k],
                                          'stddev':
                                          dust_features['fwhms_fixed'][k]
                                      })

        self.h2_features = h2_features
        if h2_features is not None:
            for k in range(len(h2_features['names'])):
                self.model += Gaussian1D(
                    name=h2_features['names'][k],
                    amplitude=h2_features['amps'][k],
                    mean=h2_features['x_0'][k],
                    stddev=h2_features['fwhms'][k] / 2.355,
                    bounds={
                        'amplitude':
                        h2_features['amps_limits'][k],
                        'mean':
                        h2_features['x_0_limits'][k],
                        'stddev': (h2_features['fwhms_limits'][k][0] / 2.355,
                                   h2_features['fwhms_limits'][k][1] / 2.355)
                    },
                    fixed={
                        'amplitude': h2_features['amps_fixed'][k],
                        'mean': h2_features['x_0_fixed'][k],
                        'stddev': h2_features['fwhms_fixed'][k]
                    })

        self.ion_features = ion_features
        if ion_features is not None:
            for k in range(len(ion_features['names'])):
                self.model += Gaussian1D(
                    name=ion_features['names'][k],
                    amplitude=ion_features['amps'][k],
                    mean=ion_features['x_0'][k],
                    stddev=ion_features['fwhms'][k] / 2.355,
                    bounds={
                        'amplitude':
                        ion_features['amps_limits'][k],
                        'mean':
                        ion_features['x_0_limits'][k],
                        'stddev': (ion_features['fwhms_limits'][k][0] / 2.355,
                                   ion_features['fwhms_limits'][k][1] / 2.355)
                    },
                    fixed={
                        'amplitude': ion_features['amps_fixed'][k],
                        'mean': ion_features['x_0_fixed'][k],
                        'stddev': ion_features['fwhms_fixed'][k]
                    })

        # apply the attenuation to *all* the components
        self.model *= S07_attenuation(
            name=att_info['names'][0],
            tau_sil=att_info['amps'][0],
            bounds={'tau_sil': att_info['amps_limits'][0]},
            fixed={'tau_sil': att_info['amps_fixed'][0]})
Exemplo n.º 16
0
    def __init__(self,
                 obs_x,
                 obs_y,
                 estimate_start=False,
                 param_info=None,
                 filename=None,
                 tformat=None):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.
        """
        # check that param_info or filename is set
        if filename is None and param_info is None:
            raise ValueError("Either param_info or filename need to be set \
                             when initializing a PAHFITBase object")

        # read in the parameter info from a file
        if filename is not None:
            param_info = self.read(filename, tformat=tformat)

        if estimate_start:
            # guess values and update starting point (if not set fixed) based on the input spectrum
            param_info = self.estimate_init(obs_x, obs_y, param_info)

        bb_info = param_info[0]
        dust_features = param_info[1]
        h2_features = param_info[2]
        ion_features = param_info[3]
        att_info = param_info[4]

        # setup the model
        self.bb_info = bb_info
        if bb_info is not None:
            # 1st component defines the overall model variable
            self.model = BlackBody1D(
                name=bb_info["names"][0],
                temperature=bb_info["temps"][0],
                amplitude=bb_info["amps"][0],
                bounds={
                    "temperature": bb_info["temps_limits"][0],
                    "amplitude": bb_info["amps_limits"][0],
                },
                fixed={
                    "temperature": bb_info["temps_fixed"][0],
                    "amplitude": bb_info["amps_fixed"][0],
                },
            )
            for k in range(1, len(bb_info["names"])):
                self.model += BlackBody1D(
                    name=bb_info["names"][k],
                    temperature=bb_info["temps"][k],
                    amplitude=bb_info["amps"][k],
                    bounds={
                        "temperature": bb_info["temps_limits"][k],
                        "amplitude": bb_info["amps_limits"][k],
                    },
                    fixed={
                        "temperature": bb_info["temps_fixed"][k],
                        "amplitude": bb_info["amps_fixed"][k],
                    },
                )

        self.dust_features = dust_features
        if dust_features is not None:
            for k in range(len(dust_features["names"])):
                self.model += Drude1D(
                    name=dust_features["names"][k],
                    amplitude=dust_features["amps"][k],
                    x_0=dust_features["x_0"][k],
                    fwhm=dust_features["fwhms"][k],
                    bounds={
                        "amplitude": dust_features["amps_limits"][k],
                        "x_0": dust_features["x_0_limits"][k],
                        "fwhm": dust_features["fwhms_limits"][k],
                    },
                    fixed={
                        "amplitude": dust_features["amps_fixed"][k],
                        "x_0": dust_features["x_0_fixed"][k],
                        "fwhm": dust_features["fwhms_fixed"][k],
                    },
                )

        self.h2_features = h2_features
        if h2_features is not None:
            for k in range(len(h2_features["names"])):
                self.model += Gaussian1D(
                    name=h2_features["names"][k],
                    amplitude=h2_features["amps"][k],
                    mean=h2_features["x_0"][k],
                    stddev=h2_features["fwhms"][k] / 2.355,
                    bounds={
                        "amplitude":
                        h2_features["amps_limits"][k],
                        "mean":
                        h2_features["x_0_limits"][k],
                        "stddev": (
                            h2_features["fwhms_limits"][k][0] / 2.355,
                            h2_features["fwhms_limits"][k][1] / 2.355,
                        ),
                    },
                    fixed={
                        "amplitude": h2_features["amps_fixed"][k],
                        "mean": h2_features["x_0_fixed"][k],
                        "stddev": h2_features["fwhms_fixed"][k],
                    },
                )

        self.ion_features = ion_features
        if ion_features is not None:
            for k in range(len(ion_features["names"])):
                self.model += Gaussian1D(
                    name=ion_features["names"][k],
                    amplitude=ion_features["amps"][k],
                    mean=ion_features["x_0"][k],
                    stddev=ion_features["fwhms"][k] / 2.355,
                    bounds={
                        "amplitude":
                        ion_features["amps_limits"][k],
                        "mean":
                        ion_features["x_0_limits"][k],
                        "stddev": (
                            ion_features["fwhms_limits"][k][0] / 2.355,
                            ion_features["fwhms_limits"][k][1] / 2.355,
                        ),
                    },
                    fixed={
                        "amplitude": ion_features["amps_fixed"][k],
                        "mean": ion_features["x_0_fixed"][k],
                        "stddev": ion_features["fwhms_fixed"][k],
                    },
                )

        # apply the attenuation to *all* the components
        self.model *= S07_attenuation(
            name=att_info["names"][0],
            tau_sil=att_info["amps"][0],
            bounds={"tau_sil": att_info["amps_limits"][0]},
            fixed={"tau_sil": att_info["amps_fixed"][0]},
        )
Exemplo n.º 17
0
def norm_gauss(sigma):
    return 1 / np.sqrt(2 * np.pi * sigma**2)


def norm_moffat(width, power):
    return G(power) / (width * np.sqrt(np.pi) * G(power - 1 / 2))


# 2 = 2*np.sqrt(2np.ln(2*sigma))
# 1 = np.ln(2*sigma)
# np.e**1 = 2*sigma
sigma = np.e / 2

x = np.arange(0, 8, 0.1)
moffat = Moffat1D(amplitude=1, x_0=0, gamma=2, alpha=2.5)
gauss = Gaussian1D(amplitude=sigma)
sb.set_context('paper', font_scale=1.5)
sb.lineplot(x=x,
            y=moffat(x) * norm_moffat(2, 2.5),
            label='Moffat, FWHM=2.2',
            linewidth=3,
            color='#870734')
sb.lineplot(x=x,
            y=gauss(x) * norm_gauss(sigma),
            label='Gaussian, FWHM=2.2',
            linewidth=3,
            color='#ef473a')
plt.xlabel('r')
plt.ylabel('Probability')
plt.savefig('gauss_vs_moffat.png', dpi=200)
Exemplo n.º 18
0
    def __init__(self, bb_info, dust_features, h2_features, ion_features):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.

        Notes
        -----
        Would be great to rename the parameters such that they uniquely
        identify the component (dust, gas, specific line, etc.).  This is
        possible - say a discussion on the stsci slack channel - James Davies?
        """
        model_comps = []
        self.bb_info = bb_info
        if bb_info is not None:
            amps = bb_info['amps']
            temps = bb_info['temps']
            amps_limits = bb_info['amps_limits']
            n_bb = len(amps)
            cont_model = BlackBody1D(temperature=temps[0],
                                     amplitude=amps[0],
                                     fixed={'temperature': True})
            cont_model.amplitude.bounds = amps_limits[0]
            for k in range(1, n_bb):
                new_model = BlackBody1D(temperature=temps[k],
                                        amplitude=amps[k],
                                        fixed={'temperature': True})
                new_model.amplitude.bounds = amps_limits[k]
                cont_model = cont_model + new_model

            self.cont_model = cont_model
            model_comps.append(cont_model)

        # dust features should be a Drude profile
        self.dust_features = dust_features
        if dust_features is not None:
            amps = dust_features['amps']
            x_0 = dust_features['x_0']
            fwhms = dust_features['fwhms']
            amps_limits = dust_features['amps_limits']
            x_0_limits = dust_features['x_0_limits']
            fwhms_limits = dust_features['fwhms_limits']
            n_df = len(amps)
            df_model = Drude1D(amplitude=amps[0],
                               x_0=x_0[0],
                               fwhm=fwhms[0],
                               bounds={
                                   'amplitude': amps_limits[0],
                                   'x_0': x_0_limits[0],
                                   'fwhm': fwhms_limits[0]
                               })
            for k in range(1, n_df):
                df_model = df_model + Drude1D(amplitude=amps[k],
                                              x_0=x_0[k],
                                              fwhm=fwhms[k],
                                              bounds={
                                                  'amplitude': amps_limits[k],
                                                  'x_0': x_0_limits[k],
                                                  'fwhm': fwhms_limits[k]
                                              })

            self.df_model = df_model
            model_comps.append(df_model)

        self.h2_features = h2_features
        if h2_features is not None:
            amps = h2_features['amps']
            x_0 = h2_features['x_0']
            fwhms = h2_features['fwhms']
            amps_limits = h2_features['amps_limits']
            x_0_limits = h2_features['x_0_limits']
            fwhms_limits = h2_features['fwhms_limits']
            names = h2_features['names']
            n_h2 = len(amps)
            h2_model = Gaussian1D(name=names[0],
                                  amplitude=amps[0],
                                  mean=x_0[0],
                                  stddev=fwhms[0] / 2.355,
                                  bounds={
                                      'amplitude':
                                      amps_limits[0],
                                      'x_0':
                                      x_0_limits[0],
                                      'stddev': (fwhms_limits[0][0] / 2.355,
                                                 fwhms_limits[0][1] / 2.355)
                                  })
            for k in range(1, n_h2):
                h2_model = h2_model + Gaussian1D(
                    name=names[k],
                    amplitude=amps[k],
                    mean=x_0[k],
                    stddev=fwhms[k] / 2.355,
                    bounds={
                        'amplitude':
                        amps_limits[k],
                        'x_0':
                        x_0_limits[k],
                        'stddev': (fwhms_limits[k][0] / 2.355,
                                   fwhms_limits[k][1] / 2.355)
                    })

            self.h2_model = h2_model
            model_comps.append(h2_model)

        self.ion_features = ion_features
        if ion_features is not None:
            amps = ion_features['amps']
            x_0 = ion_features['x_0']
            fwhms = ion_features['fwhms']
            amps_limits = ion_features['amps_limits']
            x_0_limits = ion_features['x_0_limits']
            fwhms_limits = ion_features['fwhms_limits']
            names = ion_features['names']
            n_ion = len(amps)
            ion_model = Gaussian1D(name=names[0],
                                   amplitude=amps[0],
                                   mean=x_0[0],
                                   stddev=fwhms[0] / 2.355,
                                   bounds={
                                       'amplitude':
                                       amps_limits[0],
                                       'x_0':
                                       x_0_limits[0],
                                       'stddev': (fwhms_limits[0][0] / 2.355,
                                                  fwhms_limits[0][1] / 2.355)
                                   })
            for k in range(1, n_ion):
                ion_model = ion_model + Gaussian1D(
                    name=names[k],
                    amplitude=amps[k],
                    mean=x_0[k],
                    stddev=fwhms[k] / 2.355,
                    bounds={
                        'amplitude':
                        amps_limits[k],
                        'x_0':
                        x_0_limits[k],
                        'stddev': (fwhms_limits[k][0] / 2.355,
                                   fwhms_limits[k][1] / 2.355)
                    })
            self.ion_model = ion_model
            model_comps.append(ion_model)

        self.model = model_comps[0]
        for cmodel in model_comps[1:]:
            self.model += cmodel

        # need to make the type of attenuation model a passed variable
        self.model *= S07_attenuation()
Exemplo n.º 19
0
def elo_explain_experiments():
    # Coin toss
    steps = 100
    np.random.seed(42)
    random_eval = np.random.choice([0, 1], steps)
    random_eval = [
        sum(random_eval[:i+1] == 0)/len(random_eval[:i+1])
        for i in range(len(random_eval))
    ]

    # Run against itself
    saved = evaluate(['alpha-beta', 'alpha-beta'], 4, [3, 3], steps)

    std = np.array([saved[i].sigma for i in range(len(saved))])
    mean = np.array([saved[i].mu for i in range(len(saved))])

    x = np.arange(0, 50, 0.01)

    plt.figure()
    plt.plot(x, Gaussian1D(mean=25, stddev=8.333)(x), label='Initial value')
    plt.plot(x, Gaussian1D(mean=15, stddev=6)(x), label='Player 2, loss')
    plt.plot(x, Gaussian1D(mean=35, stddev=6)(x), label='Player 1, win')

    plt.xlabel('Rating Scale')
    plt.yticks([])

    plt.axvline(15, c='gray', ls='dashed')
    plt.axvline(25, c='gray', ls='dashed')
    plt.axvline(35, c='gray', ls='dashed')

    plt.text(13.1, 0.8, '$\mu = 15$', rotation='vertical', c='k', alpha=0.4)
    plt.text(23.1, 0.8, '$\mu = 25$', rotation='vertical', c='k', alpha=0.4)
    plt.text(33.1, 0.8, '$\mu = 35$', rotation='vertical', c='k', alpha=0.4)

    plt.legend(loc=6)
    plt.tight_layout()
    plt.savefig('./output/ELO_explain1.pdf')
    plt.close()

    x = np.arange(-20, 50, 0.01)

    fig, ax1 = plt.subplots()
    ax1.plot(x, Gaussian1D(mean=10, stddev=10)(x), label='Diff. Gaussian')
    ax1.fill_between(
        np.arange(-20, 0, 0.01),
        Gaussian1D(
            mean=10,
            stddev=10
        )(np.arange(-20, 0, 0.01)),
        color='blue',
        alpha=0.3
    )

    ax1.axvline(10, c='gray', ls='dashed')
    ax1.legend(loc=6)

    cum_gaus = np.cumsum(Gaussian1D(mean=10, stddev=10)(x))

    ax2 = ax1.twinx()
    ax2.plot(x, cum_gaus/cum_gaus[-1],
             color='red', label='Cum. diff. Gaussian')
    ax2.legend(loc=5)
    ax2.set_ylabel("P(x)")
    ax1.set_ylabel('p(x) [unnormalized]')
    ax1.set_xlabel('x')

    fig.tight_layout()
    plt.savefig('./output/ELO_explain2.pdf')
    plt.close()

    indexing = np.arange(0, len(saved), 2)
    x = np.arange(steps)

    fig, ax1 = plt.subplots()
    fig.set_figwidth(10)
    fig.set_figheight(5)

    ax1.plot(random_eval, label='# of Heads in a Coin Flip')
    ax1.set_ylim(ymin=0, ymax=1)

    ax1.axhline(0.5, ls='dashed', c='gray')
    ax1.axvline(12, c='k', alpha=0.4)
    ax1.set_ylabel('p (Heads)')
    ax1.set_xlabel('Amount of Games')
    ax1.text(12.5, 0.02, 'Recommaned Cut-off',
             rotation='vertical', c='k', alpha=0.4)
    ax1.text(14.5, 0.02, 'by TrueSkill', rotation='vertical', c='k', alpha=0.4)

    ax1.legend(loc=1)

    ax2 = ax1.twinx()
    ax2.fill_between(x, y1=mean[indexing]-2 * std[indexing], y2=mean[indexing]+2 *
                     std[indexing], color='orange', alpha=0.3, label='$2\sigma$ rating uncertainty')
    ax2.plot(mean[indexing], label='Alpha-Beta, depth = 3',
             c='orange', alpha=0.7)
    ax2.fill_between(x, y1=mean[indexing+1]-2 * std[indexing+1], y2=mean[indexing+1] +
                     2*std[indexing+1], color='red', alpha=0.3, label='$2\sigma$ rating uncertainty')
    ax2.plot(mean[indexing+1], label='Alpha-Beta, depth = 3',
             c='red', alpha=0.7)

    ax2.legend(loc=4)
    ax2.axvline(24, c='k', alpha=0.4)
    ax1.text(24.5, 0.02, 'Chosen Cut-off',
             rotation='vertical', c='k', alpha=0.4)

    fig.tight_layout()
    plt.savefig('./output/ELO_convergience.pdf')
    plt.close()