Beispiel #1
0
 def __setattr__(self, attr, value):
     # TODO: Support a means of specifying default values for coefficients
     # Check for self._ndim first--if it hasn't been defined then the
     # instance hasn't been initialized yet and self.param_names probably
     # won't work.
     # This has to vaguely duplicate the functionality of
     # Parameter.__set__.
     # TODO: I wonder if there might be a way around that though...
     if attr[0] != '_' and self.param_names and attr in self.param_names:
         param = Parameter(attr, default=0.0, model=self)
         # This is a little hackish, but we can actually reuse the
         # Parameter.__set__ method here
         param.__set__(self, value)
     else:
         super(BSplineModel, self).__setattr__(attr, value)
Beispiel #2
0
class LunarLambert(DiskFunctionModel):
    """Lunar-Lambert model, or McEwen model class"""
    inputs = ('i', 'e')
    outputs = ('d',)

    L = Parameter(default=0.1, description='Partition parameter')

    @staticmethod
    def evaluate(i, e, L):
        return (1-L) * LommelSeeliger.evaluate(i, e) + L * Lambert.evaluate(i)
Beispiel #3
0
class Lorimer2006(Fittable1DModel):
    """
    Radial distribution of the suface density of pulsars in the galaxy - Lorimer 2006.

    .. math ::
        f(r) = A \\left( \\frac{r}{r_{\\odot}} \\right) ^ B \\exp
        \\left[ -C \\left( \\frac{r - r_{\\odot}}{r_{\\odot}} \\right) \\right]

    Reference: http://adsabs.harvard.edu/abs/2006MNRAS.372..777L (Formula (10))

    Parameters
    ----------
    amplitude : float
        See model formula
    B : float
        See model formula
    C : float
        See model formula

    See Also
    --------
    CaseBattacharya1998, Paczynski1990, YusifovKucuk2004, Lorimer2006,
    YusifovKucuk2004B, FaucherKaspi2006

    """
    amplitude = Parameter()
    B = Parameter()
    C = Parameter()
    evolved = True

    def __init__(self, amplitude=1, B=1.9, C=5.0, **kwargs):
        super(Lorimer2006, self).__init__(amplitude=amplitude,
                                          B=B,
                                          C=C,
                                          **kwargs)

    @staticmethod
    def evaluate(r, amplitude, B, C):
        """One dimensional Lorimer 2006 model function"""
        term1 = (r / D_SUN_TO_GALACTIC_CENTER.value)**B
        term2 = np.exp(-C * (r - D_SUN_TO_GALACTIC_CENTER.value) /
                       D_SUN_TO_GALACTIC_CENTER.value)
        return amplitude * term1 * term2
Beispiel #4
0
class Beta(Fittable1DModel):
    s0 = Parameter(default = 1e-2, min = 1e-12)
    beta = Parameter(default = 0.7, min = 1e-12)
    rc = Parameter(default = 0.1, min = 1e-12)
    const = Parameter(default = 1e-3, min=1e-12)

    @staticmethod
    def evaluate(x, s0, beta, rc, const):
        result = s0 * (1. + (x/rc)**2) ** (0.5 - 3*beta) + const
        return result

    @staticmethod
    def fit_deriv(x, s0, beta, rc, const):
        d_s0 = (1. + (x/rc)**2) ** (0.5 - 3*beta)
        d_beta = -3 * s0 * np.log(1. + (x/rc)**2) * \
                 (1. + (x/rc)**2) ** (0.5 - 3*beta)
        d_rc = -2 * s0 * x**2 * (0.5 - 3*beta) / rc**3 \
               * (1. + (x/rc)**2) ** (-0.5 - 3*beta)
        return [d_s0, d_beta, d_rc, np.ones_like(x)]
Beispiel #5
0
class YusifovKucuk2004(Fittable1DModel):
    """Radial distribution of the surface density of pulsars in the galaxy - Yusifov & Kucuk 2004.

    .. math ::
        f(r) = A \\left ( \\frac{r + r_1}{r_{\\odot} + r_1} \\right )^a \\exp
        \\left [-b \\left( \\frac{r - r_{\\odot}}{r_{\\odot} + r_1} \\right ) \\right ]

    Used by Faucher-Guigere and Kaspi. Density at ``r = 0`` is nonzero.

    Reference: http://adsabs.harvard.edu/abs/2004A%26A...422..545Y (Formula (15))

    Parameters
    ----------
    amplitude : float
        See model formula
    a : float
        See model formula
    b : float
        See model formula
    r_1 : float
        See model formula

    See Also
    --------
    CaseBattacharya1998, Paczynski1990, Lorimer2006, YusifovKucuk2004B,
    FaucherKaspi2006, Exponential
    """
    amplitude = Parameter()
    a = Parameter()
    b = Parameter()
    r_1 = Parameter()
    evolved = True

    def __init__(self, amplitude=1, a=1.64, b=4.01, r_1=0.55, **kwargs):
        super(YusifovKucuk2004, self).__init__(amplitude=amplitude,
                                               a=a, b=b, r_1=r_1, **kwargs)

    @staticmethod
    def evaluate(r, amplitude, a, b, r_1):
        """One dimensional Yusifov & Kucuk 2004 model function"""
        term1 = ((r + r_1) / (D_SUN_TO_GALACTIC_CENTER.value + r_1)) ** a
        term2 = np.exp(-b * (r - D_SUN_TO_GALACTIC_CENTER.value) / (D_SUN_TO_GALACTIC_CENTER.value + r_1))
        return amplitude * term1 * term2
Beispiel #6
0
class CaseBattacharya1998(Fittable1DModel):
    """Radial distribution of the surface density of supernova remnants in the galaxy - Case & Battacharya 1998.

    .. math ::
        f(r) = A \\left( \\frac{r}{r_{\\odot}} \\right) ^ \\alpha \\exp
        \\left[ -\\beta \\left( \\frac{ r - r_{\\odot}}{r_{\\odot}} \\right) \\right]

    Reference: http://adsabs.harvard.edu//abs/1998ApJ...504..761C (Formula (14))

    Parameters
    ----------
    amplitude : float
        See model formula
    alpha : float
        See model formula
    beta : float
        See model formula

    See Also
    --------
    Paczynski1990, YusifovKucuk2004, Lorimer2006, YusifovKucuk2004B,
    FaucherKaspi2006, Exponential
    """

    amplitude = Parameter()
    alpha = Parameter()
    beta = Parameter()
    evolved = True

    def __init__(self, amplitude=1., alpha=2, beta=3.53, **kwargs):
        super(CaseBattacharya1998, self).__init__(amplitude=amplitude,
                                                  alpha=alpha,
                                                  beta=beta,
                                                  **kwargs)

    @staticmethod
    def evaluate(r, amplitude, alpha, beta):
        """Evaluate model."""
        term1 = (r / D_SUN_TO_GALACTIC_CENTER.value)**alpha
        term2 = np.exp(-beta * (r - D_SUN_TO_GALACTIC_CENTER.value) /
                       D_SUN_TO_GALACTIC_CENTER.value)
        return amplitude * term1 * term2
Beispiel #7
0
class FaucherKaspi2006VelocityBimodal(Fittable1DModel):
    """Bimodal pulsar velocity distribution - Faucher & Kaspi (2006).

    .. math ::
        f(v) = A\\sqrt{\\frac{2}{\\pi}} v^2 \\left[\\frac{w}{\\sigma_1^3}
        \\exp \\left(-\\frac{v^2}{2\\sigma_1^2} \\right) + \\frac{1-w}{\\sigma_2^3}
        \\exp \\left(-\\frac{v^2}{2\\sigma_2^2} \\right) \\right]

    Reference: http://adsabs.harvard.edu/abs/2006ApJ...643..332F (Formula (7))

    Parameters
    ----------
    amplitude : float
        Value of the integral
    sigma1 : float
        See model formula
    sigma2 : float
        See model formula
    w : float
        See model formula
    """

    amplitude = Parameter()
    sigma_1 = Parameter()
    sigma_2 = Parameter()
    w = Parameter()

    def __init__(self, amplitude=1, sigma_1=160, sigma_2=780, w=0.9, **kwargs):
        super(FaucherKaspi2006VelocityBimodal,
              self).__init__(amplitude=amplitude,
                             sigma_1=sigma_1,
                             sigma_2=sigma_1,
                             w=w,
                             **kwargs)

    @staticmethod
    def evaluate(v, amplitude, sigma_1, sigma_2, w):
        """One dimensional Faucher-Guigere & Kaspi 2006 velocity model function."""
        A = amplitude * np.sqrt(2 / np.pi) * v**2
        term1 = (w / sigma_1**3) * np.exp(-v**2 / (2 * sigma_1**2))
        term2 = (1 - w) / sigma_2**3 * np.exp(-v**2 / (2 * sigma_2**2))
        return A * (term1 + term2)
Beispiel #8
0
class YusifovKucuk2004B(Fittable1DModel):
    """Radial distribution of the surface density of OB stars in the galaxy - Yusifov & Kucuk 2004.

    .. math ::
        f(r) = A \\left( \\frac{r}{r_{\\odot}} \\right) ^ a
        \\exp \\left[ -b \\left( \\frac{r}{r_{\\odot}} \\right) \\right]

    Derived empirically from OB-stars distribution.

    Reference: http://adsabs.harvard.edu/abs/2004A%26A...422..545Y (Formula (17))

    Parameters
    ----------
    amplitude : float
        See model formula
    a : float
        See model formula
    b : float
        See model formula

    See Also
    --------
    CaseBattacharya1998, Paczynski1990, YusifovKucuk2004, Lorimer2006,
    FaucherKaspi2006, Exponential
    """

    amplitude = Parameter()
    a = Parameter()
    b = Parameter()
    evolved = False

    def __init__(self, amplitude=1, a=4, b=6.8, **kwargs):
        super(YusifovKucuk2004B, self).__init__(amplitude=amplitude,
                                                a=a,
                                                b=b,
                                                **kwargs)

    @staticmethod
    def evaluate(r, amplitude, a, b):
        """Evaluate model."""
        return amplitude * (r / D_SUN_TO_GALACTIC_CENTER.value)**a * np.exp(
            -b * (r / D_SUN_TO_GALACTIC_CENTER.value))
class GaussianLine(Fittable1DModel):
	"""
	A model for line emission using a Gaussian
	"""
	
	amplitude = Parameter(min=0)
	fwhm = Parameter(min=0)
	x_0 = Parameter(min=0)
	
	def evaluate(self, x, amplitude, fwhm, x_0):
		sig = fwhm/2.3548
		return amplitude * np.exp(-(x - x_0)**2/(2*sig**2))
		
	def luminosity(self, ldist):
		lam = np.arange(-1000, 1000, 0.001)
		nu = 3e14/(lam)
		f = self(lam)
		f_int = -np.trapz(f, nu) / 10**23
		b = 4*np.pi*(ldist*10**6*3.086e18)**2
		return f_int*b
Beispiel #10
0
class LinearExp(FittableModel):
    inputs = ('t', )
    outputs = ('flux', )

    amplitude = Parameter()
    rise_time = Parameter()
    decay_tau = Parameter()
    t0 = Parameter(default=0.)

    @staticmethod
    def evaluate(t, amplitude, rise_time, decay_tau, t0):
        if np.ndim(t) == 0:
            t = np.asarray(t, dtype=np.float).reshape((1, ))
        t_offset = t - t0
        vals = np.zeros_like(t_offset, dtype=np.float)
        rise_idx = np.logical_and(t_offset >= -rise_time, t_offset <= 0)
        fall_idx = t_offset > 0
        vals[rise_idx] = (1 + t_offset[rise_idx] / rise_time)
        vals[fall_idx] = np.exp(-t_offset[fall_idx] / decay_tau)
        return amplitude * vals
Beispiel #11
0
class BlackBody1D(Fittable1DModel):
    """
    Current astropy BlackBody1D does not play well with Lorentz1D and Gauss1D
    maybe, need to check again, possibly a units issue
    """

    amplitude = Parameter()
    temperature = Parameter()

    @staticmethod
    def evaluate(x, amplitude, temperature):
        """
        """
        return (
            amplitude
            * ((9.7 / x) ** 2)
            * 3.97289e13
            / x ** 3
            / (np.exp(1.4387752e4 / x / temperature) - 1.0)
        )
Beispiel #12
0
class LinearPhaseFunc(DiskIntegratedModelClass):
    """Linear phase function model

    Examples
    --------
    >>> # Define a linear phase function model with absolute magnitude
    >>> # H = 5 and slope = 0.04 mag/deg = 2.29 mag/rad
    >>> from sbpy.photometry import LinearPhaseFunc
    >>>
    >>> linear_phasefunc = LinearPhaseFunc(5, 2.29, radius=300)
    >>> pha = np.linspace(0, 180, 200)
    >>> mag = linear_phasefunc.mag(np.deg2rad(pha))
    >>> ref = linear_phasefunc.ref(np.deg2rad(pha))
    >>> geoalb = linear_phasefunc.geoalb
    >>> phaseint = linear_phasefunc.phaseint
    >>> bondalb = linear_phasefunc.bondalb
    >>> print('Geometric albedo is {0:.3}'.format(geoalb))
    Geometric albedo is 0.0501
    >>> print('Bond albedo is {0:.3}'.format(bondalb))
    Bond albedo is 0.0184
    >>> print('Phase integral is {0:.3}'.format(phaseint))
    Phase integral is 0.368

    """

    _unit = 'mag'
    H = Parameter(description='Absolute magnitude')
    S = Parameter(description='Linear slope (mag/rad)')

    @staticmethod
    def evaluate(a, H, S):
        return H + S * a

    @staticmethod
    def fit_deriv(a, H, S):
        if hasattr(a, '__iter__'):
            ddh = np.ones_like(a)
        else:
            ddh = 1.
        dds = a
        return [ddh, dds]
Beispiel #13
0
class GaussHermite1D(Fittable1DModel):
    """
    Gauss-Hermite Series up to the fourth order.

    Parameters
    ----------
    amplitude : float
        Integrated flux of the profile.
    mean : float
        Coordinate of the profile center.
    stddev : float
        Sigma
    h3 : float
        Coefficient of the third order element.
    h4 : float
        Coefficient of the fourth order element.

    Description
    -----------
    Taken from Riffel, R. A. 2010 and van der Marel & Franx 1993.
    """

    inputs = ('x', )
    outputs = ('y', )

    amplitude = Parameter(default=1)
    mean = Parameter(default=0)
    stddev = Parameter(default=1)
    h3 = Parameter(default=0)
    h4 = Parameter(default=0)

    @staticmethod
    def evaluate(x, amplitude, mean, stddev, h3, h4):

        w = (x - mean) / stddev

        alphag = np.exp(-w**2. / 2.) / np.sqrt(2. * np.pi)
        hh3 = h3 * np.sqrt(2.) / np.sqrt(6.) * (2. * w**3 - 3. * w)
        hh4 = h4 / np.sqrt(24.) * (4. * w**4 - 12. * w**2 + 3.)

        return amplitude * alphag / stddev * (1. + hh3 + hh4)
Beispiel #14
0
class EINASTO2(Fittable1DModel):
    '''Einasto dark matter halo model
    Inputs:
        r:  array_like
            Radius in Kpc. Must be non negative.

        rho_e2: float or int.
                rho_e2  in Msol/pc3.
        r_e2:   float or int.
                r_e2 in Kpc.
        mu:     float or int.
                no units
    Outputs
        v:  array_like
            velocity in km/s.
    '''
    inputs = ('r', )
    outputs = ('v', )

    rho_e2 = Parameter(bounds=(1e-8, 1e3))
    r_e2 = Parameter(bounds=(1e-8, 300))
    mu = Parameter(bounds=(0, 20))
    fit_deriv = None

    @staticmethod
    def evaluate(r, rho_e2, r_e2, mu):
        '''Einasto dark matter model function
        '''
        r = r * u.kpc
        rho_e2 = rho_e2 * u.M_sun / (u.pc**3)
        rho_e2 = rho_e2.to(u.M_sun / (u.kpc**3))
        r_e2 = r_e2 * u.kpc  # rayon de densite rho2
        dn = 2.0 * mu
        xx = dn * np.power(r / r_e2, 1.0 / mu)
        igma = gammainc(3 * mu, xx.value) * gamma(3 * mu)
        v = np.sqrt(G * 4 * np.pi * np.power(r_e2, 3) * rho_e2 *
                    np.power(2.0, -3.0 * mu) * np.power(mu, 1.0 - 3 * mu) *
                    np.exp(dn) * igma / r)
        v = v.to(u.km / u.s)
        v = v.value
        return (v)
Beispiel #15
0
class FaucherKaspi2006(Fittable1DModel):
    """Radial distribution of the birth surface density of pulsars in the galaxy - Faucher-Giguere & Kaspi 2006.

    .. math ::
        f(r) = A \\frac{1}{\\sqrt{2 \pi} \sigma} \\exp
        \\left(- \\frac{(r - r_0)^2}{2 \sigma ^ 2}\\right)

    Reference: http://adsabs.harvard.edu/abs/2006ApJ...643..332F (Appendix B)

    Parameters
    ----------
    amplitude : float
        See model formula
    r_0 : float
        See model formula
    sigma : float
        See model formula

    See Also
    --------
    CaseBattacharya1998, Paczynski1990, YusifovKucuk2004, Lorimer2006,
    YusifovKucuk2004B, Exponential
    """

    amplitude = Parameter()
    r_0 = Parameter()
    sigma = Parameter()
    evolved = False

    def __init__(self, amplitude=1, r_0=7.04, sigma=1.83, **kwargs):
        super(FaucherKaspi2006, self).__init__(amplitude=amplitude,
                                               r_0=r_0,
                                               sigma=sigma,
                                               **kwargs)

    @staticmethod
    def evaluate(r, amplitude, r_0, sigma):
        """Evaluate model."""
        term1 = 1. / np.sqrt(2 * pi * sigma)
        term2 = np.exp(-(r - r_0)**2 / (2 * sigma**2))
        return amplitude * term1 * term2
Beispiel #16
0
class RSquared(FittableModel):
    inputs = ('epoch', 'luminosity', )
    outputs = ('epoch', 'luminosity_density',)

    #Distance in Mpc
    distance = Parameter()


    def evaluate(self, epoch, luminosity, distance):
        luminosity_density = (luminosity /
                              (4 * np.pi * (distance * mpc_to_cm)**2))
        return epoch, luminosity_density
Beispiel #17
0
class TwoDScale(Model):
    n_inputs = 2
    n_outputs = 2
    scale = Parameter()
    separable = False

    def evaluate(self, x, y, scale=1 * u.deg):
        return u.Quantity([x, y]) * scale

    @property
    def inverse(self):
        return TwoDScale(1 / self.scale)
Beispiel #18
0
class Parsec(StarKitModel):

    mh = Parameter()
    mass = Parameter()
    age = Parameter()

    inputs = ()
    outputs = ('teff', 'logg', 'lum')

    def __init__(self, parsec_store, mh=0.0, mass=1.0, age=5e9):
        super(Parsec, self).__init__(mh, mass, age)
        try:
            self.parsec_store = pd.HDFStore(parsec_store)
        except TypeError:
            self.parsec_store = parsec_store

        self.evolution_data = [
            self.parsec_store[key] for key in self.parsec_store.keys()
        ]
        self.parsec_store.close()
        self.mh_mass = np.empty((len(self.evolution_data), 2))

        for i, ev_data in enumerate(self.evolution_data):
            mh = ev_data['MH'][0]
            mass = ev_data['MASS'][0]
            self.mh_mass[i] = mh, mass

        self.mh_mass_kd_tree = KDTree(self.mh_mass)

    def evaluate(self, mh, mass, age):
        distance, idx = self.mh_mass_kd_tree.query(
            np.array([mh, mass]).squeeze())
        ev_data = self.evolution_data[idx]
        age_ev_data = ev_data['AGE'].values
        out_ev_data = ev_data[['TEFF', 'LOG_G', 'LOG_L']].values
        teff, logg, log_l = interpolate.interp1d(age_ev_data,
                                                 out_ev_data.T,
                                                 bounds_error=False)(
                                                     np.squeeze(age))
        return teff, logg, 10**log_l
Beispiel #19
0
class ModSigmoidExp(FittableModel):
    """
    Sigmoidal rise / exponential decay modulated by a quadratic polynomial.

    Typically applied as a supernova optical-lightcurve model,
    applicable to all SNe types.

    Following Karpenka et al 2012; Eq 1.
    ( http://adsabs.harvard.edu/abs/2013MNRAS.429.1278K )
    """
    inputs = ('t', )
    outputs = ('flux', )

    a = Parameter()
    b = Parameter()
    t1_minus_t0 = Parameter()
    rise_tau = Parameter()
    decay_tau = Parameter()
    t0 = Parameter(default=0.)

    @staticmethod
    def evaluate(t, a, b, t1_minus_t0, rise_tau, decay_tau, t0):
        t_offset = t - t0
        t_minus_t1 = t_offset - t1_minus_t0
        b_fac = 1 + b * t_minus_t1 * t_minus_t1
        #NB imported 'truediv' behaviour, so OK even if t0, decay both integers.
        exp_num = np.exp(-t_offset / decay_tau)
        exp_denom = 1 + np.exp(-t_offset / rise_tau)
        return a * b_fac * exp_num / exp_denom
Beispiel #20
0
class ModGauss1D(Fittable1DModel):
    r"""
    Modified Gaussian
    """
    n_inputs = 1
    n_outputs = 1

    scale = Parameter(default=1.0)
    x_o = Parameter(default=3.0, min=0.0)
    gamma_o = Parameter(default=1.0, min=0.0)
    asym = Parameter(default=0.0)

    @staticmethod
    def evaluate(x, scale, x_o, gamma_o, asym):
        """

        Parameters
        ----------
        x : float
            input wavelengths

        scale : float
            central amplitude

        x_o : float
            central wavelength

        gamma_o : float
            full-width-half-maximum of profile

        asym : float
            asymmetry where a value of 0 results in a standard Drude profile
        """
        # gamma replaces FWHM, so stddev=gamma/(2sqrt(2ln2))
        gamma = 2.0 * gamma_o / (1.0 + np.exp(asym * (x - x_o)))
        y = scale * np.exp(
            -((x - x_o) ** 2) / (2 * (gamma / (2 * np.sqrt(2 * np.log(2)))) ** 2)
        )
        return y
Beispiel #21
0
class GaussExp(FittableModel):
    inputs = ('t', )
    outputs = ('flux', )

    amplitude = Parameter()
    rise_tau = Parameter()
    decay_tau = Parameter()
    t0 = Parameter(default=0.)

    @staticmethod
    def evaluate(t, amplitude, rise_tau, decay_tau, t0):
        if np.ndim(t) == 0:
            t = np.asarray(t, dtype=np.float).reshape((1, ))
        t_offset = t - t0
        vals = np.zeros_like(t_offset, dtype=np.float)
        #NB vals outside offset_min/max limits taken care of by LightcurveBase
        rise_idx = t_offset <= 0.
        fall_idx = t_offset > 0.
        vals[rise_idx] = np.exp(-1. * t_offset[rise_idx] * t_offset[rise_idx] /
                                (2. * rise_tau * rise_tau))
        vals[fall_idx] = np.exp(-t_offset[fall_idx] / decay_tau)
        return amplitude * vals
Beispiel #22
0
class NegativeQuadratic(FittableModel):
    """
    Very simple example, used for testing purposes.
    """

    inputs = ('t', )
    outputs = ('flux', )
    amplitude = Parameter()
    t0 = Parameter(default=0.0)

    @staticmethod
    def evaluate(t, amplitude, t0):
        if np.ndim(t) == 0:
            t = np.asarray(t, dtype=np.float).reshape((1, ))
        t_offset = t - t0
        root = np.sqrt(amplitude)
        t_valid = (t_offset > -root) & (t_offset < root)
        # print "t_offset", t_offset
        # print "T_valid", t_valid
        vals = np.zeros_like(t_offset)
        vals[t_valid] = amplitude - t_offset[t_valid]**2
        return vals
Beispiel #23
0
    def _load_parameters(self):
        """Function to load parameters from the sub-model"""
        if self._parameters is not None:
            # do nothing
            return

        self._parameters_ = {}
        self._param_names = []

        for param_name, param_val in zip(self._model.param_names, self._model.parameters):
            param = Parameter(param_name, default=param_val)
            self.__dict__[param_name] = param
            self._parameters_[param_name] = param
            self._param_names.append(param_name)

        param_name = 'psf_pa'
        param = Parameter(param_name, default=0)
        self.__dict__[param_name] = param
        self._parameters_[param_name] = param
        self._param_names.append(param_name)

        self._param_names = tuple(self._param_names)
Beispiel #24
0
    class Gaussian1D(Fittable1DModelPlugin):
        amplitude = Parameter("amplitude")
        mean = Parameter("mean")
        stddev = Parameter("stddev")

        @staticmethod
        def evaluate(x, amplitude, mean, stddev):
            """
            Gaussian1D model function.
            """
            return amplitude * np.exp(-0.5 * (x - mean)**2 / stddev**2)

        @staticmethod
        def fit_deriv(x, amplitude, mean, stddev):
            """
            Gaussian1D model function derivatives.
            """

            d_amplitude = np.exp(-0.5 / stddev**2 * (x - mean)**2)
            d_mean = amplitude * d_amplitude * (x - mean) / stddev**2
            d_stddev = amplitude * d_amplitude * (x - mean)**2 / stddev**3
            return [d_amplitude, d_mean, d_stddev]
Beispiel #25
0
class VanDerLaan(FittableModel):
    """

    """
    inputs = ('t', )
    outputs = ('flux', )

    # maximum_flux
    amplitude = Parameter()
    energy_index = Parameter()
    # maximum_time
    t0 = Parameter(default=0.)

    @staticmethod
    def evaluate(t, amplitude, energy_index, t0):
        maximum_flux = amplitude
        maximum_time = t0
        vals = np.zeros_like(t, dtype=np.float)
        index = t >= 0.

        # parameters that are derived from inputs and physics parameters
        distance = 3.09e19  # place holder distance of 1 kiloparsec
        initial_tau_0_guess = 10.
        tau_m = fsolve(tau_0_solve, initial_tau_0_guess, energy_index)
        size_at_peak_flux = ((maximum_flux * distance * distance / np.pi) *
                             (1. / (1. - np.exp(-tau_m))))**0.5
        expansion_speed = size_at_peak_flux / maximum_time

        # assume that the cloud expands linearly
        relative_size = 1. + ((expansion_speed / size_at_peak_flux) *
                              (t - maximum_time))

        numerator = 1. - np.exp(
            -tau_m * relative_size**(-2. * energy_index - 3.))
        denominator = 1. - np.exp(-tau_m)
        vals[index] = (relative_size**3.) * numerator / denominator

        return maximum_flux * vals
class gaussian(Fittable1DModel):
    '''A two-faced gaussian based on the version in stsdas.contrib.specfit

    Effectively, this gaussian has two different sigmas on each side of the
    mean. For values less than the mean, the sigma is as specified. For values
    greater than the mean, the new sigma = skew * specified sigma

    Units for fwhm are km/s
    norm represents total flux (presumably in arbitrary units)
    mean is called the centroid, but that seems misleading. It is the maximum
    of the dual faced gaussian.

    The units of mean and x should be consistent.

    '''
    norm = Parameter(default=1)
    mean = Parameter(default=0)
    fwhm = Parameter(default=1)
    skew = Parameter(default=1)

    @staticmethod
    def evaluate(x, norm, mean, fwhm, skew):
        return bipolar_gaussian(x, norm, mean, fwhm, skew)
Beispiel #27
0
class Shift2D(FittableModel):
    """2D translation"""

    if ASTROPY_LT_40:
        inputs = ('x', 'y')
        outputs = ('x', 'y')
    else:
        n_inputs = 2
        n_outputs = 2

    x_offset = Parameter(default=0.0)
    y_offset = Parameter(default=0.0)

    @property
    def inverse(self):
        inv = self.copy()
        inv.x_offset = -self.x_offset
        inv.y_offset = -self.y_offset
        return inv

    @staticmethod
    def evaluate(x, y, x_offset, y_offset):
        return x + x_offset, y + y_offset
Beispiel #28
0
class sl(Fittable1DModel):
    """
    Model for starlight calculation
    """
    star_temp = 5000.

    Star_tau = Parameter(description="star_tau_T5000", default=5e-12, min=0.0)

    @staticmethod
    def evaluate(in_x, Star_tau):

        y = Star_tau * blackbody(in_x, sl.star_temp)

        return y
class Drude(Fittable1DModel):
	"""
	Drude profile to use for dust features in IRS spectra.
	"""
	
	amplitude = Parameter(min=0)
	fwhm = Parameter(min=0)
	x_0 = Parameter(min=0)
		
	def evaluate(self, x, amplitude, fwhm, x_0):
		num = amplitude * (fwhm/x_0)**2
		denom = (x/x_0 - x_0/x)**2 + (fwhm/x_0)**2
		return num/denom


	def luminosity(self, ldist):
		"""
		Calculate luminosity of Drude profile for a specific luminosity distance.
		ldist = luminosity distance in Mpc
		"""
		a = np.pi*3e14/2.*self.amplitude*(self.fwhm/self.x_0)/self.x_0/10**23
		b = 4*np.pi*(ldist*10**6*3.086e18)**2
		return a*b
Beispiel #30
0
class DifferentialRefraction(Fittable1DModel):
    """
    See Filippenko, A. 1982 (PASP 94, 715).

    Wavelengths must be in microns!
    """
    n_inputs = 1
    n_outputs = 1

    temperature = Parameter(default=7.0, min=-60.0, max=40.0)
    pressure = Parameter(default=500.0, min=100.0, max=800.0)
    water_vapour = Parameter(default=8.0, min=0.0, max=800.0)
    air_mass = Parameter(default=1.5, min=1.0, max=5.0)
    wl_0 = Parameter(default=5000.0)

    @staticmethod
    def evaluate(x, temperature, pressure, water_vapour, air_mass, wl_0):

        def n_lambda(wavelength):
            r = np.square(1.0 / wavelength)
            a = 29498.1 / (146.0 - r)
            b = 255.4 / (41.0 - r)
            n_sea_level = 1e-6 * (64.328 + a + b)

            a = 1.0 + (1.049 - (0.0157 * temperature)) * 1e-6 * pressure
            b = 720.883 * (1.0 + 0.003661 * temperature)
            n_tp = n_sea_level * pressure * (a / b)

            a = 0.0624 - (0.000680 * r)
            b = 1.0 + (0.003661 * temperature)
            water_factor = water_vapour * (a / b) * 1e-6

            return n_tp - water_factor

        k = np.tan(np.arcsin(1 / air_mass))
        delta_r = 206265.0 * (n_lambda(x * 1e-4) - n_lambda(wl_0 * 1e-4)) * k
        return delta_r
Beispiel #31
0
class NFW(Fittable1DModel):
    '''Navarro-Frenk-White halo model

    Inputs:
        r:  array_like.
            Radius in Kpc. Must be non negative.

        par_list:   list, of length 2, of
                    Parameters of NFW model.
                    par_list[0]:    float or int.
                                    v200  in km/s
                    par_list[1]:    float or int.
                                    concentration parameter, no units.
    Outputs
        v:
            velocity in km/s.
    '''
    inputs = ('r', )
    outputs = ('v', )

    v200 = Parameter(bounds=(0, 200))
    c = Parameter(bounds=(1e-12, 30))
    fit_deriv = None

    @staticmethod
    def evaluate(r, v200, c):
        r = r * u.kpc
        v200 = v200 * u.km / u.s
        r200 = (v200 / cosmo.H0).to(u.kpc)
        # r200 = (v200/(68.0*u.km/u.s/u.Mpc)*100).to(u.kpc)
        # r200 = v200/cosmo.h*1e3
        x = r / r200
        v = v200 * np.power((np.log(1.0 + c * x) - c * x / (1.0 + c * x)) /
                            (x * (np.log(1.0 + c) - c / (1.0 + c))), 0.5)
        v = v.to(u.km / u.s)
        v = v.value
        return (v)