Ejemplo n.º 1
0
def test_equivalency_context_manager():
    base_registry = u.get_current_unit_registry()

    def just_to_from_units(equivalencies):
        return [(equiv[0], equiv[1]) for equiv in equivalencies]

    tf_dimensionless_angles = just_to_from_units(u.dimensionless_angles())
    tf_spectral = just_to_from_units(u.spectral())
    assert base_registry.equivalencies == []
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        new_registry = u.get_current_unit_registry()
        assert (set(just_to_from_units(new_registry.equivalencies)) ==
                set(tf_dimensionless_angles))
        assert set(new_registry.all_units) == set(base_registry.all_units)
        with u.set_enabled_equivalencies(u.spectral()):
            newer_registry = u.get_current_unit_registry()
            assert (set(just_to_from_units(newer_registry.equivalencies)) ==
                    set(tf_spectral))
            assert (set(newer_registry.all_units) ==
                    set(base_registry.all_units))

        assert (set(just_to_from_units(new_registry.equivalencies)) ==
                set(tf_dimensionless_angles))
        assert set(new_registry.all_units) == set(base_registry.all_units)
        with u.add_enabled_equivalencies(u.spectral()):
            newer_registry = u.get_current_unit_registry()
            assert (set(just_to_from_units(newer_registry.equivalencies)) ==
                    set(tf_dimensionless_angles) | set(tf_spectral))
            assert (set(newer_registry.all_units) ==
                    set(base_registry.all_units))

    assert base_registry is u.get_current_unit_registry()
Ejemplo n.º 2
0
def test_equivalency_context_manager():
    base_registry = u.get_current_unit_registry()

    def just_to_from_units(equivalencies):
        return [(equiv[0], equiv[1]) for equiv in equivalencies]

    tf_dimensionless_angles = just_to_from_units(u.dimensionless_angles())
    tf_spectral = just_to_from_units(u.spectral())
    assert base_registry.equivalencies == []
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        new_registry = u.get_current_unit_registry()
        assert (set(just_to_from_units(new_registry.equivalencies)) ==
                set(tf_dimensionless_angles))
        assert set(new_registry.all_units) == set(base_registry.all_units)
        with u.set_enabled_equivalencies(u.spectral()):
            newer_registry = u.get_current_unit_registry()
            assert (set(just_to_from_units(newer_registry.equivalencies)) ==
                    set(tf_spectral))
            assert (set(newer_registry.all_units) ==
                    set(base_registry.all_units))

        assert (set(just_to_from_units(new_registry.equivalencies)) ==
                set(tf_dimensionless_angles))
        assert set(new_registry.all_units) == set(base_registry.all_units)
        with u.add_enabled_equivalencies(u.spectral()):
            newer_registry = u.get_current_unit_registry()
            assert (set(just_to_from_units(newer_registry.equivalencies)) ==
                    set(tf_dimensionless_angles) | set(tf_spectral))
            assert (set(newer_registry.all_units) ==
                    set(base_registry.all_units))

    assert base_registry is u.get_current_unit_registry()
Ejemplo n.º 3
0
 def setup_class(self):
     """set up some initial values for tests"""
     u.set_enabled_equivalencies(u.temperature_energy())
     self.T_e = 1000 * u.eV
     self.n_e = 2e13 / u.cm**3
     self.ion_particle = 'D +1'
     self.m_i = particle_mass(self.ion_particle)
     self.Z = integer_charge(self.ion_particle)
     self.T_i = self.T_e
     self.n_i = self.n_e / self.Z
     self.B = 0.01 * u.T
     self.coulomb_log_val_ei = 17
     self.coulomb_log_val_ii = 17
     self.hall_e = None
     self.hall_i = None
     self.V_ei = None
     self.V_ii = None
     self.mu = m_e / self.m_i
     self.theta = self.T_e / self.T_i
     self.model = 'Braginskii'
     self.field_orientation = 'all'
     with pytest.warns(RelativityWarning):
         self.ct = ClassicalTransport(
             T_e=self.T_e,
             n_e=self.n_e,
             T_i=self.T_i,
             n_i=self.n_i,
             ion_particle=self.ion_particle,
             Z=self.Z,
             B=self.B,
             model=self.model,
             field_orientation=self.field_orientation,
             coulomb_log_ei=self.coulomb_log_val_ei,
             coulomb_log_ii=self.coulomb_log_val_ii,
             V_ei=self.V_ei,
             V_ii=self.V_ii,
             hall_e=self.hall_e,
             hall_i=self.hall_i,
             mu=self.mu,
             theta=self.theta,
         )
         self.ct_wrapper = ClassicalTransport(
             T_e=self.T_e,
             n_e=self.n_e,
             T_i=self.T_i,
             n_i=self.n_i,
             ion_particle=self.ion_particle,
             Z=self.Z,
             B=self.B,
             model=self.model,
             field_orientation=self.field_orientation,
             mu=self.mu,
             theta=self.theta,
         )
         self.all_variables = self.ct.all_variables()
Ejemplo n.º 4
0
def mean_motion(orbit, tof, **kwargs):
    r"""Propagates orbit using mean motion

    .. versionadded:: 0.9.0

    Parameters
    ----------
    orbit : ~poliastro.twobody.orbit.Orbit
        the Orbit object to propagate.
    tof : float
        Time of flight (s).

    Notes
    -----
    This method takes initial :math:`\vec{r}, \vec{v}`, calculates classical orbit parameters,
    increases mean anomaly and performs inverse transformation to get final :math:`\vec{r}, \vec{v}`
    The logic is based on formulae (4), (6) and (7) from http://dx.doi.org/10.1007/s10569-013-9476-9

    """

    k = orbit.attractor.k.to(u.km**3 / u.s**2).value
    r0 = orbit.r.to(u.km).value
    v0 = orbit.v.to(u.km / u.s).value

    # get the initial true anomaly and orbit parameters that are constant over time
    p, ecc, inc, raan, argp, nu0 = rv2coe(k, r0, v0)

    # get the initial mean anomaly
    M0 = nu_to_M(nu0, ecc)
    # elliptic or hyperbolic orbits
    if not np.isclose(ecc, 1.0, rtol=1e-06):
        a = p / (1.0 - ecc**2)
        # given the initial mean anomaly, calculate mean anomaly
        # at the end, mean motion (n) equals sqrt(mu / |a^3|)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            M = M0 + tof * np.sqrt(k / np.abs(a**3)) * u.rad
            nu = M_to_nu(M, ecc)

    # parabolic orbit
    else:
        q = p / 2.0
        # mean motion n = sqrt(mu / 2 q^3) for parabolic orbit
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            M = M0 + tof * np.sqrt(k / (2.0 * q**3))

        # using Barker's equation, which is solved analytically
        # for parabolic orbit, get true anomaly
        B = 3.0 * M / 2.0
        A = (B + np.sqrt(1.0 + B**2))**(2.0 / 3.0)
        D = 2.0 * A * B / (1.0 + A + A**2)

        nu = 2.0 * np.arctan(D)
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        return coe2rv(k, p, ecc, inc, raan, argp, nu)
Ejemplo n.º 5
0
def mean_motion(k, r0, v0, tof, **kwargs):
    r"""Propagates orbit using mean motion

    Parameters
    ----------
    k : float
        Gravitational constant of main attractor (km^3 / s^2).
    r0 : array
        Initial position (km).
    v0 : array
        Initial velocity (km).
    ad : function(t0, u, k), optional
         Non Keplerian acceleration (km/s2), default to None.
    tof : float
        Time of flight (s).

    Notes
    -----
    This method takes initial :math:`\vec{r}, \vec{v}`, calculates classical orbit parameters,
    increases mean anomaly and performs inverse transformation to get final :math:`\vec{r}, \vec{v}`
    The logic is based on formulae (4), (6) and (7) from http://dx.doi.org/10.1007/s10569-013-9476-9

    """

    # get the initial true anomaly and orbit parameters that are constant over time
    p, ecc, inc, raan, argp, nu0 = rv2coe(k, r0, v0)

    # get the initial mean anomaly
    M0 = nu_to_M(nu0, ecc)
    # elliptic or hyperbolic orbits
    if not np.isclose(ecc, 1.0, rtol=1e-06):
        a = p / (1.0 - ecc**2)
        # given the initial mean anomaly, calculate mean anomaly
        # at the end, mean motion (n) equals sqrt(mu / |a^3|)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            M = M0 + tof * np.sqrt(k / np.abs(a**3)) * u.rad
            nu = M_to_nu(M, ecc)

    # parabolic orbit
    else:
        q = p / 2.0
        # mean motion n = sqrt(mu / 2 q^3) for parabolic orbit
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            M = M0 + tof * np.sqrt(k / (2.0 * q**3))

        # using Barker's equation, which is solved analytically
        # for parabolic orbit, get true anomaly
        B = 3.0 * M / 2.0
        A = (B + np.sqrt(1.0 + B**2))**(2.0 / 3.0)
        D = 2.0 * A * B / (1.0 + A + A**2)

        nu = 2.0 * np.arctan(D)
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        return coe2rv(k, p, ecc, inc, raan, argp, nu)
Ejemplo n.º 6
0
def _convert(quantity, dispersion_unit, dispersion, flux_unit):
    """
    Convert the quantity to the spectrum's units, and then we will use
    the *value* of it in the new unitless-model.
    """
    with u.set_enabled_equivalencies(u.spectral()):
        if quantity.unit.is_equivalent(dispersion_unit):
            quantity = quantity.to(dispersion_unit)

    with u.set_enabled_equivalencies(u.spectral_density(dispersion)):
        if quantity.unit.is_equivalent(flux_unit):
            quantity = quantity.to(flux_unit)

    return quantity
Ejemplo n.º 7
0
 def world_to_pixel(self, world_array):
     """
     Method for performing the world to pixel transformations.
     """
     with u.set_enabled_equivalencies(u.spectral()):
         world_array = u.Quantity(world_array, unit=self.spectral_axis_unit)
     return self.axes.spectral.all_world2pix(world_array.value, 0)[0]
Ejemplo n.º 8
0
 def d_spindown_phase_d_delay(self, toas, delay):
     dt_tzrmjd, dt_pepoch = self.get_dt(toas, delay)
     fterms = [0.0] + self.get_spin_terms()
     with u.set_enabled_equivalencies(dimensionless_cycles):
         d_ptzrmjd_d_delay = taylor_horner_deriv((dt_tzrmjd-dt_pepoch).to( \
                                                  u.second), fterms)
         return -d_ptzrmjd_d_delay.to(u.cycle / u.second)
Ejemplo n.º 9
0
 def test_kkiternanfailure(self):
     """
     Make sure that KK iteration stops instantly when it starts
     producing NaNs. Producing NaNs means that the iteration has
     been given input parameters which fail
     to converge to anything sane.
     """
     testspec = helpers.generate_absspectrum()
     assert testspec.x.unit == u.kayser
     assert testspec.y.unit == utils.unit_od
     testspec.subspectrum(2200., 3900.)
     freq = testspec.x
     transmittance = testspec.y.to(
         utils.unit_transmittance,
         equivalencies=utils.equivalencies_absorption)
     m_substrate = 1.74+0.0j  # CsI window, like in the Hudgins paper
     d_ice = 0.5*u.micron
     m0 = 1.3 + 0.0j
     with u.set_enabled_equivalencies(u.equivalencies.spectral()):
         freq_m0 = (250.*u.micron).to(u.kayser).value
     with pytest.raises(utils.KKError):
         with warnings.catch_warnings():
             warnings.simplefilter("ignore")
             utils.kramers_kronig(
                 freq,
                 transmittance,
                 m_substrate,
                 d_ice,
                 m0,
                 freq_m0)
Ejemplo n.º 10
0
    def d_phase_d_toa(self, toas, sample_step=None):
        """Return the derivative of phase wrt TOA
        Parameter
        ---------
        toas : PINT TOAs class
            The toas when the derivative of phase will be evaluated at.
        sample_step : float optional
            Finite difference steps. If not specified, it will take 1/10 of the
            spin period.
        """
        copy_toas = copy.deepcopy(toas)
        if sample_step is None:
            pulse_period = 1.0 / (self.F0.quantity)
            sample_step = pulse_period * 1000
        sample_dt = [-sample_step, 2 * sample_step]

        sample_phase = []
        for dt in sample_dt:
            dt_array = ([dt.value] * copy_toas.ntoas*dt._unit)
            deltaT = time.TimeDelta(dt_array)
            copy_toas.adjust_TOAs(deltaT)
            phase = self.phase(copy_toas.table)
            sample_phase.append(phase)
        #Use finite difference method.
        # phase'(t) = (phase(t+h)-phase(t-h))/2+ 1/6*F2*h^2 + ..
        # The error should be near 1/6*F2*h^2
        dp = (sample_phase[1] - sample_phase[0])
        d_phase_d_toa = dp.int / (2*sample_step) + dp.frac / (2*sample_step)
        del copy_toas
        with u.set_enabled_equivalencies(dimensionless_cycles):
            return d_phase_d_toa.to(u.Hz)
Ejemplo n.º 11
0
    def test_raise_to_power(self, power):
        """Check that raising LogQuantities to some power is only possible when
        the physical unit is dimensionless, and that conversion is turned off
        when the resulting logarithmic unit (say, mag**2) is incompatible."""
        lq = u.Magnitude(np.arange(1., 4.)*u.Jy)

        if power == 0:
            assert np.all(lq ** power == 1.)
        elif power == 1:
            assert np.all(lq ** power == lq)
        else:
            with pytest.raises(u.UnitsError):
                lq ** power

        # with dimensionless, it works, but falls back to normal quantity
        # (except for power=1)
        lq2 = u.Magnitude(np.arange(10.))

        t = lq2**power
        if power == 0:
            assert t.unit is u.dimensionless_unscaled
            assert np.all(t.value == 1.)
        elif power == 1:
            assert np.all(t == lq2)
        else:
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit ** power
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(u.dimensionless_unscaled)
Ejemplo n.º 12
0
    def test_raise_to_power(self, power):
        """Check that raising LogUnits to some power is only possible when the
        physical unit is dimensionless, and that conversion is turned off when
        the resulting logarithmic unit (such as mag**2) is incompatible."""
        lu1 = u.mag(u.Jy)

        if power == 0:
            assert lu1 ** power == u.dimensionless_unscaled
        elif power == 1:
            assert lu1 ** power == lu1
        else:
            with pytest.raises(u.UnitsError):
                lu1 ** power

        # With dimensionless, though, it works, but returns a normal unit.
        lu2 = u.mag(u.dimensionless_unscaled)

        t = lu2**power
        if power == 0:
            assert t == u.dimensionless_unscaled
        elif power == 1:
            assert t == lu2
        else:
            assert not isinstance(t, type(lu2))
            assert t == lu2.function_unit**power
            # also check we roundtrip
            t2 = t**(1./power)
            assert t2 == lu2.function_unit
            with u.set_enabled_equivalencies(u.logarithmic()):
                assert_allclose(t2.to(u.dimensionless_unscaled, np.arange(3.)),
                                lu2.to(lu2.physical_unit, np.arange(3.)))
Ejemplo n.º 13
0
    def glitch_phase(self, toas, delay):
        """Glitch phase function.
        delay is the time delay from the TOA to time of pulse emission
        at the pulsar, in seconds.
        returns an array of phases in long double
        """
        tbl = toas.table
        phs = numpy.zeros_like(tbl, dtype=numpy.longdouble) * u.cycle
        glepnames = [x for x in self.params if x.startswith('GLEP_')]
        with u.set_enabled_equivalencies(dimensionless_cycles):
            for glepnm in glepnames:
                glep = getattr(self, glepnm)
                eph = glep.value
                idx = glep.index
                dphs = getattr(self, "GLPH_%d" % idx).quantity
                dF0 = getattr(self, "GLF0_%d" % idx).quantity
                dF1 = getattr(self, "GLF1_%d" % idx).quantity
                dF2 = getattr(self, "GLF2_%d" % idx).quantity
                dt = (tbl['tdbld'] - eph) * u.day - delay
                dt = dt.to(u.second)
                affected = dt > 0.0  # TOAs affected by glitch
                # decay term
                dF0D = getattr(self, "GLF0D_%d" % idx).quantity
                if dF0D != 0.0:
                    tau = getattr(self, "GLTD_%d" % idx).quantity
                    decayterm = dF0D * tau * (1.0 - numpy.exp(- (dt[affected]
                                              / tau).to(u.Unit(""))))
                else:
                    decayterm = 0.0

                phs[affected] += dphs + dt[affected] * \
                    (dF0 + 0.5 * dt[affected] * dF1 + \
                     1./6. * dt[affected]*dt[affected] * dF2) + decayterm
            return phs.to(u.cycle)
Ejemplo n.º 14
0
 def d_nu_d_T0(self):
     """dnu/dT0 = dnu/de*de/dT0+dnu/dE*dE/dT0
        de/dT0 = -EDOT
     """
     with u.set_enabled_equivalencies(u.dimensionless_angles()):
         return self.d_nu_d_ecc() * (
             -self.EDOT) + self.d_nu_d_E() * self.d_E_d_T0()
Ejemplo n.º 15
0
    def d_Dre_d_par(self, par):
        """Dre = alpha*(cos(E)-er)+(beta+gamma)*sin(E)
           dDre = alpha*(-der-dE*sin(E)) + (cos[E]-er)*dalpha +
                  (dBeta+dGamma)*sin(E) + (beta+gamma)*cos(E)*dE

           dDre/dpar = alpha*(-der/dpar-dE/dpar*sin(E)) +
                       (cos[E]-er)*dalpha/dpar +
                       (dBeta/dpar+dGamma/dpar)*sin(E) +
                       (beta+gamma)*cos(E)*dE/dpar

            er = e + Dr
        """
        Dre = self.Dre()
        par_obj = getattr(self, par)
        sinE = np.sin(self.E())
        cosE = np.cos(self.E())
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            # First term
            term1 = self.alpha() * (-self.prtl_der('er', par) -
                                    self.prtl_der('E', par) * sinE)
            # Second term
            term2 = (cosE - self.er()) * self.prtl_der('alpha', par)
            # Third term
            term3 = (self.prtl_der('beta', par) +
                     self.prtl_der('GAMMA', par)) * sinE
            # Fourth term
            term4 = (self.beta() + self.GAMMA) * cosE * self.prtl_der('E', par)

            return (term1 + term2 + term3 + term4).to(Dre.unit / par_obj.unit)
Ejemplo n.º 16
0
    def d_alpha_d_par(self, par):
        """T. Damour and N. Deruelle(1986)equation [46]
           alpha = a1/c*sin(omega)
           dAlpha/dpar = d_a1_d_par /c * sin(omega) + a1/c*cos(omega)*dOmega/dPar
        """

        if par not in self.binary_params:
            errorMesg = par + "is not in binary parameter list."
            raise ValueError(errorMesg)
        par_obj = getattr(self, par)
        alpha = self.alpha()
        sinOmg = np.sin(self.omega())
        cosOmg = np.cos(self.omega())
        a1 = self.a1()
        d_a1_d_par = self.d_a1_d_par(par)
        d_omega_d_par = self.d_omega_d_par(par)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            dAlpha_dpar = d_a1_d_par / c.c * sinOmg + a1 / c.c * cosOmg * d_omega_d_par
        #
        # if par in ['A1','A1DOT']:
        #     dername = 'd_alpha_d_'+par
        #     return getattr(self,dername)()
        #
        # else:
        #     dername = 'd_omega_d_'+par # For parameters only in Ae
        #     if hasattr(self,dername):
        #         cosOmg=np.cos(self.omega())
        #         return self.a1()/c.c*cosOmg*getattr(self,dername)()
        #     else:
        #         return np.longdouble(np.zeros(len(self.tt0)))
        return dAlpha_dpar.to(alpha.unit / par_obj.unit)
Ejemplo n.º 17
0
    def d_delayI_d_par(self,par):
        """Derivative on delay inverse.
        """
        e = self.ecc()
        sE = np.sin(self.E())
        cE = np.cos(self.E())
        dE_dpar = self.prtl_der('E',par)
        decc_dpar = self.prtl_der('ecc',par)

        Dre = self.Dre()
        Drep = self.Drep()
        Drepp = self.Drepp()
        nHat = self.nhat()
        delayI = self.delayInverse()

        dDre_dpar = self.d_Dre_d_par(par)
        dDrep_dpar = self.d_Drep_d_par(par)
        dDrepp_dpar = self.d_Drepp_d_par(par)
        dnhat_dpar = self.d_nhat_d_par(par)
        oneMeccTcosE = (1-e*cE) # 1-e*cos(E)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            x =  -1.0/2.0*e*sE/oneMeccTcosE # -1/2*e*sin(E)/(1-e*cos(E))

            dx_dpar = -sE/(2*oneMeccTcosE**2)*decc_dpar+e*(e-cE)/(2*oneMeccTcosE**2)*dE_dpar

            diDelay_dDre = 1+(Drep*nHat)**2+Dre*Drepp*nHat**2+Drep*nHat*(2*Dre*nHat*x-1)
            diDelay_dDrep = Dre*nHat*(2*Drep*nHat+Dre*nHat*x-1)
            diDelay_dDrepp = (Dre*nHat)**2/2
            diDelay_dnhat = Dre*(-Drep+2*Drep**2*nHat+nHat*Dre*Drepp+2*x*nHat*Dre*Drep)
            diDelay_dx = (Dre*nHat)**2*Drep

            return dDre_dpar*diDelay_dDre + dDrep_dpar*diDelay_dDrep + \
                   dDrepp_dpar*diDelay_dDrepp + dx_dpar*diDelay_dx+ \
                   dnhat_dpar*diDelay_dnhat
Ejemplo n.º 18
0
    def d_beta_d_par(self, par):
        """beta = A1/c*(1-eTheta**2)**0.5*cos(omega)
           eTheta = ecc+Dth  ??
           dBeta/dA1 = 1.0/c*(1-eTheta**2)**0.5*cos(omega)
           dBeta/dECC = A1/c*((-(e+dr)/sqrt(1-(e+dr)**2)*cos(omega)*de/dECC-
                        (1-eTheta**2)**0.5*sin(omega)*domega/dECC
           dBeta/dEDOT = A1/c*((-(e+dr)/sqrt(1-(e+dr)**2)*cos(omega)*de/dEDOT-
                        (1-eTheta**2)**0.5*sin(omega)*domega/dEDOT
           dBeta/dDth = A1/c*(-(e+dr)/sqrt(1-(e+dr)**2)*cos(omega)
           Other parameters
           dBeta/dPar = -A1/c*(1-eTheta**2)**0.5*sin(omega)*dOmega/dPar
        """
        if par not in self.binary_params:
            errorMesg = par + "is not in binary parameter list."
            raise ValueError(errorMesg)
        par_obj = getattr(self, par)
        beta = self.beta()
        eTheta = self.eTheta()
        a1 = self.a1()
        omega = self.omega()
        sinOmg = np.sin(omega)
        cosOmg = np.cos(omega)
        d_a1_d_par = self.d_a1_d_par(par)
        d_omega_d_par = self.d_omega_d_par(par)
        d_eTheta_d_par = self.d_eTheta_d_par(par)

        d_beta_d_a1 = 1.0 / c.c * (1 - eTheta**2)**0.5 * cosOmg
        d_beta_d_omega = -a1 / c.c * (1 - eTheta**2)**0.5 * sinOmg
        d_beta_d_eTheta = a1 / c.c * (-eTheta) / np.sqrt(1 -
                                                         eTheta**2) * cosOmg
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            return (d_beta_d_a1 * d_a1_d_par + d_beta_d_omega * d_omega_d_par + \
                    d_beta_d_eTheta * d_eTheta_d_par).to(beta.unit/par_obj.unit)
Ejemplo n.º 19
0
    def d_Dre_d_par(self,par):
        """Dre = alpha*(cos(E)-er)+(beta+gamma)*sin(E)
           dDre = alpha*(-der-dE*sin(E)) + (cos[E]-er)*dalpha +
                  (dBeta+dGamma)*sin(E) + (beta+gamma)*cos(E)*dE

           dDre/dpar = alpha*(-der/dpar-dE/dpar*sin(E)) +
                       (cos[E]-er)*dalpha/dpar +
                       (dBeta/dpar+dGamma/dpar)*sin(E) +
                       (beta+gamma)*cos(E)*dE/dpar

            er = e + Dr
        """
        Dre = self.Dre()
        par_obj = getattr(self, par)
        sinE = np.sin(self.E())
        cosE = np.cos(self.E())
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            # First term
            term1 = self.alpha()*(-self.prtl_der('er',par)-self.prtl_der('E',par)*sinE)
            # Second term
            term2 = (cosE-self.er())*self.prtl_der('alpha',par)
            # Third term
            term3 = (self.prtl_der('beta',par)+self.prtl_der('GAMMA',par))*sinE
            # Fourth term
            term4 = (self.beta()+self.GAMMA)*cosE*self.prtl_der('E',par)

            return (term1 + term2 + term3 +term4).to(Dre.unit/par_obj.unit)
Ejemplo n.º 20
0
    def d_beta_d_par(self,par):
        """beta = A1/c*(1-eTheta**2)**0.5*cos(omega)
           eTheta = ecc+Dth  ??
           dBeta/dA1 = 1.0/c*(1-eTheta**2)**0.5*cos(omega)
           dBeta/dECC = A1/c*((-(e+dr)/sqrt(1-(e+dr)**2)*cos(omega)*de/dECC-
                        (1-eTheta**2)**0.5*sin(omega)*domega/dECC
           dBeta/dEDOT = A1/c*((-(e+dr)/sqrt(1-(e+dr)**2)*cos(omega)*de/dEDOT-
                        (1-eTheta**2)**0.5*sin(omega)*domega/dEDOT
           dBeta/dDth = A1/c*(-(e+dr)/sqrt(1-(e+dr)**2)*cos(omega)
           Other parameters
           dBeta/dPar = -A1/c*(1-eTheta**2)**0.5*sin(omega)*dOmega/dPar
        """
        if par not in self.binary_params:
            errorMesg = par + "is not in binary parameter list."
            raise ValueError(errorMesg)
        par_obj = getattr(self, par)
        beta = self.beta()
        eTheta = self.eTheta()
        a1 = self.a1()
        omega = self.omega()
        sinOmg = np.sin(omega)
        cosOmg = np.cos(omega)
        d_a1_d_par = self.d_a1_d_par(par)
        d_omega_d_par = self.d_omega_d_par(par)
        d_eTheta_d_par = self.d_eTheta_d_par(par)

        d_beta_d_a1 = 1.0/c.c*(1-eTheta**2)**0.5*cosOmg
        d_beta_d_omega = -a1/c.c*(1-eTheta**2)**0.5*sinOmg
        d_beta_d_eTheta = a1/c.c*(-eTheta)/np.sqrt(1-eTheta**2)*cosOmg
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            return (d_beta_d_a1 * d_a1_d_par + d_beta_d_omega * d_omega_d_par + \
                    d_beta_d_eTheta * d_eTheta_d_par).to(beta.unit/par_obj.unit)
Ejemplo n.º 21
0
    def d_alpha_d_par(self,par):
        """T. Damour and N. Deruelle(1986)equation [46]
           alpha = a1/c*sin(omega)
           dAlpha/dpar = d_a1_d_par /c * sin(omega) + a1/c*cos(omega)*dOmega/dPar
        """

        if par not in self.binary_params:
            errorMesg = par + "is not in binary parameter list."
            raise ValueError(errorMesg)
        par_obj = getattr(self, par)
        alpha = self.alpha()
        sinOmg = np.sin(self.omega())
        cosOmg = np.cos(self.omega())
        a1 = self.a1()
        d_a1_d_par = self.d_a1_d_par(par)
        d_omega_d_par = self.d_omega_d_par(par)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            dAlpha_dpar = d_a1_d_par / c.c * sinOmg + a1 / c.c * cosOmg * d_omega_d_par
        #
        # if par in ['A1','A1DOT']:
        #     dername = 'd_alpha_d_'+par
        #     return getattr(self,dername)()
        #
        # else:
        #     dername = 'd_omega_d_'+par # For parameters only in Ae
        #     if hasattr(self,dername):
        #         cosOmg=np.cos(self.omega())
        #         return self.a1()/c.c*cosOmg*getattr(self,dername)()
        #     else:
        #         return np.longdouble(np.zeros(len(self.tt0)))
        return dAlpha_dpar.to(alpha.unit/par_obj.unit)
Ejemplo n.º 22
0
    def d_delayS_d_par(self, par):
        if set(self.fit_params) == set(["H3", "H4"]):
            stigma = self.H4 / self.H3
        elif set(self.fit_params) == set(["H3", "STIGMA"]):
            stigma = self.STIGMA
        elif set(self.fit_params) == set(["H3"]):
            stigma = 0.0
        else:
            raise NotImplementedError("ELL1H did not implemented %s parameter"
                                      " set yet." % str(self.fit_params))

        d_ds_func_name_base = "d_" + self.ds_func.__name__ + "_d_"
        d_delayS_d_H3_func = getattr(self, d_ds_func_name_base + "H3")
        d_delayS_d_Phi_func = getattr(self, d_ds_func_name_base + "Phi")
        d_delayS_d_STIGMA_func = getattr(self, d_ds_func_name_base + "STIGMA")

        d_delayS_d_H3 = d_delayS_d_H3_func(self.H3, stigma, self.NHARMS)
        d_delayS_d_Phi = d_delayS_d_Phi_func(self.H3, stigma, self.NHARMS)
        d_delayS_d_STIGMA = d_delayS_d_STIGMA_func(self.H3, stigma,
                                                   self.NHARMS)

        d_H3_d_par = self.prtl_der("H3", par)
        d_Phi_d_par = self.prtl_der("Phi", par)
        d_STIGMA_d_par = self.prtl_der("STIGMA", par)

        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            d_delayS_d_par = (d_delayS_d_H3 * d_H3_d_par +
                              d_delayS_d_Phi * d_Phi_d_par +
                              d_delayS_d_STIGMA * d_STIGMA_d_par)
        return d_delayS_d_par
Ejemplo n.º 23
0
    def d_delayS_d_par(self,par):
        """dsDelay/dPar = dsDelay/dTM2*dTM2/dPar+
                          dsDelay/decc*decc/dPar+
                          dsDelay/dE*dE/dPar+
                          dsDelay/domega*domega/dPar+
                          dsDelay/dSINI*dSINI/dPar
        """
        e = self.ecc()
        cE = np.cos(self.E())
        sE = np.sin(self.E())
        sOmega = np.sin(self.omega())
        cOmega = np.cos(self.omega())
        TM2 = self.M2.value*Tsun

        logNum = 1-e*cE-self.SINI*(sOmega*(cE-e)+
                 (1-e**2)**0.5*cOmega*sE)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            dTM2_dpar = self.prtl_der('TM2',par)
            dsDelay_dTM2 = -2*np.log(logNum)
            decc_dpar = self.prtl_der('ecc',par)
            dsDelay_decc = -2*TM2/logNum*(-cE-self.SINI*(-e*cOmega*sE/np.sqrt(1-e**2)-sOmega))
            dE_dpar = self.prtl_der('E',par)
            dsDelay_dE =  -2*TM2/logNum*(e*sE-self.SINI*(np.sqrt(1-e**2)*cE*cOmega-sE*sOmega))
            domega_dpar = self.prtl_der('omega',par)
            dsDelay_domega = 2*TM2/logNum*self.SINI*((cE-e)*cOmega-np.sqrt(1-e**2)*sE*sOmega)
            dSINI_dpar = self.prtl_der('SINI',par)
            dsDelay_dSINI = -2*TM2/logNum*(-(1-e**2)**0.5*cOmega*sE-(cE-e)*sOmega)
            return dTM2_dpar*dsDelay_dTM2 + decc_dpar*dsDelay_decc + \
                   dE_dpar*dsDelay_dE +domega_dpar*dsDelay_domega +  \
                   dSINI_dpar*dsDelay_dSINI
Ejemplo n.º 24
0
    def __init__(self, wn, m, **kwargs):
        """
    CDESpectrum(wn,m,**kwargs)

    Constructor for the `CDESpectrum` class.

    Parameters
    ----------
    wn : `astropy.units.Quantity` or `numpy.ndarray`
      The absorption spectrum frequency data. If given as
      `astropy.units.Quantity`, they must either be in kayser (reciprocal
      wavenumbers) or convertable to kayser. If given as `numpy.ndarray`,
      they are assumed to be in kayser.
    m : `numpy.ndarray`
      The complex refractive index spectrum of the data.
    **kwargs : Arguments, optional
      Additional initialisation arguments can be passed to
      `AbsorptionSpectrum` using this. Note that x and y are defined using
      the other initialisation parameters of `CDESpectrum`.
    """
        if len(wn) != len(m):
            raise RuntimeError("Input arrays have different sizes.")
        if type(wn) != u.quantity.Quantity:
            wn = wn * u.kayser
        if wn.unit != u.kayser:
            with u.set_enabled_equivalencies(u.equivalencies.spectral()):
                wn = wn.to(u.kayser)
        self.cabs, self.cabs_vol, self.cscat_vol, self.ctot = utils.cde_correct(wn.value, m)
        self.m = np.array(m, dtype="float64")
        od = (
            self.cabs_vol * utils.unit_od
        )  # utils.unit_absorbance).to(utils.unit_od,equivalencies=utils.equivalencies_absorption)
        AbsorptionSpectrum.__init__(self, wn, od, **kwargs)
Ejemplo n.º 25
0
 def d_spindown_phase_d_delay(self, toas, delay):
     dt_tzrmjd, dt_pepoch = self.get_dt(toas, delay)
     fterms = [0.0] + self.get_spin_terms()
     with u.set_enabled_equivalencies(dimensionless_cycles):
         d_ptzrmjd_d_delay = taylor_horner_deriv((dt_tzrmjd-dt_pepoch).to( \
                                                  u.second), fterms)
         return -d_ptzrmjd_d_delay.to(u.cycle/u.second)
Ejemplo n.º 26
0
    def glitch_phase(self, toas, delay):
        """Glitch phase function.
        delay is the time delay from the TOA to time of pulse emission
        at the pulsar, in seconds.
        returns an array of phases in long double
        """
        tbl = toas.table
        phs = np.zeros_like(tbl, dtype=np.longdouble) * u.cycle
        glepnames = [x for x in self.params if x.startswith('GLEP_')]
        with u.set_enabled_equivalencies(dimensionless_cycles):
            for glepnm in glepnames:
                glep = getattr(self, glepnm)
                eph = glep.value
                idx = glep.index
                dphs = getattr(self, "GLPH_%d" % idx).quantity
                dF0 = getattr(self, "GLF0_%d" % idx).quantity
                dF1 = getattr(self, "GLF1_%d" % idx).quantity
                dF2 = getattr(self, "GLF2_%d" % idx).quantity
                dt = (tbl['tdbld'] - eph) * u.day - delay
                dt = dt.to(u.second)
                affected = dt > 0.0  # TOAs affected by glitch
                # decay term
                dF0D = getattr(self, "GLF0D_%d" % idx).quantity
                if dF0D != 0.0:
                    tau = getattr(self, "GLTD_%d" % idx).quantity
                    decayterm = dF0D * tau * (
                        1.0 - np.exp(-(dt[affected] / tau).to(u.Unit(""))))
                else:
                    decayterm = 0.0

                phs[affected] += dphs + dt[affected] * \
                    (dF0 + 0.5 * dt[affected] * dF1 + \
                     1./6. * dt[affected]*dt[affected] * dF2) + decayterm
            return phs.to(u.cycle)
Ejemplo n.º 27
0
def test_dimensionless_redshift():
    """Test :func:`astropy.cosmology.units.dimensionless_redshift`."""
    z = 3 * cu.redshift
    val = 3 * u.one

    # show units not equal
    assert z.unit == cu.redshift
    assert z.unit != u.one

    # test equivalency enabled by default
    assert z == val

    # also test that it works for powers
    assert (3 * cu.redshift ** 3) == val

    # and in composite units
    assert (3 * u.km / cu.redshift ** 3) == 3 * u.km

    # test it also works as an equivalency
    with u.set_enabled_equivalencies([]):  # turn off default equivalencies
        assert z.to(u.one, equivalencies=cu.dimensionless_redshift()) == val

        with pytest.raises(ValueError):
            z.to(u.one)

    # if this fails, something is really wrong
    with u.add_enabled_equivalencies(cu.dimensionless_redshift()):
        assert z == val
Ejemplo n.º 28
0
def latexForWavelength(unitlike):
    un = unit(unitlike)
    with u.set_enabled_equivalencies([]):
        if un.is_equivalent(unit("m")): return r"$\lambda$"
        if un.is_equivalent(unit("Hz")): return r"$\nu$"
        if un.is_equivalent(unit("J")): return r"$E$"
    return ""
Ejemplo n.º 29
0
    def d_delayS_d_par(self, par):
        """Derivative for bianry Shaprio delay.

        Computes::

            delayS = -2 * TM2 * np.log(1 - self.SINI * np.sin(Phi))
            d_delayS_d_par = d_delayS_d_TM2 * d_TM2_d_par + d_delayS_d_SINI*d_SINI_d_par +
                             d_delayS_d_Phi * d_Phi_d_par
        """
        TM2 = self.TM2()
        Phi = self.Phi()
        d_delayS_d_TM2 = -2 * np.log(1 - self.SINI * np.sin(Phi))
        d_delayS_d_SINI = (
            -2 * TM2 * 1.0 / (1 - self.SINI * np.sin(Phi)) * (-np.sin(Phi))
        )
        d_delayS_d_Phi = -2 * TM2 * 1.0 / (1 - self.SINI * np.sin(Phi)) * (-self.SINI)
        d_TM2_d_par = self.prtl_der("TM2", par)
        d_SINI_d_par = self.prtl_der("SINI", par)
        d_Phi_d_par = self.prtl_der("Phi", par)

        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            d_delayS_d_par = (
                d_delayS_d_TM2 * d_TM2_d_par
                + d_delayS_d_SINI * d_SINI_d_par
                + d_delayS_d_Phi * d_Phi_d_par
            )
        return d_delayS_d_par
Ejemplo n.º 30
0
 def world_to_pixel(self, world_array):
     """
     Method for performing the world to pixel transformations.
     """
     with u.set_enabled_equivalencies(u.spectral()):
         world_array = u.Quantity(world_array, unit=self.spectral_axis_unit)
     return self.axes.spectral.all_world2pix(world_array.value, 0)[0]
Ejemplo n.º 31
0
    def test_raise_to_power(self, power):
        """Check that raising LogUnits to some power is only possible when the
        physical unit is dimensionless, and that conversion is turned off when
        the resulting logarithmic unit (such as mag**2) is incompatible."""
        lu1 = u.mag(u.Jy)

        if power == 0:
            assert lu1**power == u.dimensionless_unscaled
        elif power == 1:
            assert lu1**power == lu1
        else:
            with pytest.raises(u.UnitsError):
                lu1**power

        # With dimensionless, though, it works, but returns a normal unit.
        lu2 = u.mag(u.dimensionless_unscaled)

        t = lu2**power
        if power == 0:
            assert t == u.dimensionless_unscaled
        elif power == 1:
            assert t == lu2
        else:
            assert not isinstance(t, type(lu2))
            assert t == lu2.function_unit**power
            # also check we roundtrip
            t2 = t**(1. / power)
            assert t2 == lu2.function_unit
            with u.set_enabled_equivalencies(u.logarithmic()):
                assert_allclose(t2.to(u.dimensionless_unscaled, np.arange(3.)),
                                lu2.to(lu2.physical_unit, np.arange(3.)))
Ejemplo n.º 32
0
    def d_phase_d_toa(self, toas, sample_step=None):
        """Return the derivative of phase wrt TOA.

        Parameters
        ----------
        toas : PINT TOAs class
            The toas when the derivative of phase will be evaluated at.
        sample_step : float optional
            Finite difference steps. If not specified, it will take 1/10 of the
            spin period.

        """
        copy_toas = copy.deepcopy(toas)
        if sample_step is None:
            pulse_period = 1.0 / (self.F0.quantity)
            sample_step = pulse_period * 1000
        sample_dt = [-sample_step, 2 * sample_step]

        sample_phase = []
        for dt in sample_dt:
            dt_array = ([dt.value] * copy_toas.ntoas * dt._unit)
            deltaT = time.TimeDelta(dt_array)
            copy_toas.adjust_TOAs(deltaT)
            phase = self.phase(copy_toas)
            sample_phase.append(phase)
        #Use finite difference method.
        # phase'(t) = (phase(t+h)-phase(t-h))/2+ 1/6*F2*h^2 + ..
        # The error should be near 1/6*F2*h^2
        dp = (sample_phase[1] - sample_phase[0])
        d_phase_d_toa = dp.int / (2 * sample_step) + dp.frac / (2 *
                                                                sample_step)
        del copy_toas
        with u.set_enabled_equivalencies(dimensionless_cycles):
            return d_phase_d_toa.to(u.Hz)
Ejemplo n.º 33
0
def isotropic_w0(N=100):
    # positions
    d = np.random.lognormal(mean=np.log(25), sigma=0.5, size=N)
    phi = np.random.uniform(0, 2 * np.pi, size=N)
    theta = np.arccos(np.random.uniform(size=N) - 0.5)

    vr = np.random.normal(150., 40., size=N) * u.km / u.s
    vt = np.random.normal(100., 40., size=N)
    vt = np.vstack((vt, np.zeros_like(vt))).T

    # rotate to be random position angle
    pa = np.random.uniform(0, 2 * np.pi, size=N)
    M = np.array([[np.cos(pa), -np.sin(pa)], [np.sin(pa), np.cos(pa)]]).T
    vt = np.array([vv.dot(MM) for (vv, MM) in zip(vt, M)]) * u.km / u.s
    vphi, vtheta = vt.T

    rep = coord.PhysicsSphericalRepresentation(r=d * u.dimensionless_unscaled,
                                               phi=phi * u.radian,
                                               theta=theta * u.radian)
    x = rep.represent_as(coord.CartesianRepresentation).xyz.T.value

    vr = vr.decompose(galactic).value * u.one
    vphi = vphi.decompose(galactic).value * u.one
    vtheta = vtheta.decompose(galactic).value * u.one

    vsph = coord.PhysicsSphericalDifferential(d_phi=vphi / (d * np.sin(theta)),
                                              d_theta=vtheta / d,
                                              d_r=vr)

    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        v = vsph.represent_as(coord.CartesianDifferential,
                              base=rep).d_xyz.value.T

    return np.hstack((x, v)).T
Ejemplo n.º 34
0
    def d_Drepp_d_par(self, par):
        """Derivative.

        Computes::

            Drepp = -alpha*cos(E)-(beta+GAMMA)*sin(E)
            dDrepp = -(beta+gamma)*cos(E)*dE - cos(E)*dalpha
                     +alpha*sin(E)*dE - (dbeta+dgamma)*sin(E)
            dDrepp/dPar = -cos(E)*dalpha/dPar
                          +(alpha*sin(E)-(beta+gamma)*cos(E))*dE/dPar
                          -(dbeta/dPar+dgamma/dPar)*sin(E)
        """
        sinE = np.sin(self.E())
        cosE = np.cos(self.E())
        Drepp = self.Drepp()
        par_obj = getattr(self, par)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            # first term
            term1 = -cosE * self.prtl_der("alpha", par)
            # second term
            term2 = (self.alpha() * sinE -
                     (self.beta() + self.GAMMA) * cosE) * self.prtl_der(
                         "E", par)
            # Third term
            term3 = -sinE * (self.prtl_der("beta", par) +
                             self.prtl_der("GAMMA", par))

            return (term1 + term2 + term3).to(Drepp.unit / par_obj.unit)
Ejemplo n.º 35
0
 def d_phase_d_jump(self, toas, jump_param, delay):
     jpar = getattr(self, jump_param)
     d_phase_d_j = numpy.zeros(len(toas))
     mask = jpar.select_toa_mask(toas)
     d_phase_d_j[mask] = self.F0.value
     with u.set_enabled_equivalencies(dimensionless_cycles):
         return (d_phase_d_j * self.F0.units).to(u.cycle/u.second)
Ejemplo n.º 36
0
 def __new__(cls, arg1, arg2=None):
     # Assume inputs are numerical, could add an extra
     # case to parse strings as input.
     # if it is not a list, convert to a list
     if not hasattr(arg1, 'unit'):
         arg1 = arg1 * u.cycle
     if arg1.shape == ():
         arg1 = arg1.reshape((1,))
     with u.set_enabled_equivalencies(dimensionless_cycles):
         arg1 = arg1.to(u.Unit(""))
         # Since modf does not like dimensioned quantity
         if arg2 is None:
             ff,ii = numpy.modf(arg1)
         else:
             if not hasattr(arg2, 'unit'):
                 arg2 = arg2 * u.cycle
             if arg2.shape == ():
                 arg2 = arg2.reshape((1,))
             arg2 = arg2.to(u.Unit(""))
             arg1S = numpy.modf(arg1)
             arg2S = numpy.modf(arg2)
             ii = arg1S[1]+arg2S[1]
             ff = arg2S[0]
         index = numpy.where(ff < -0.5)
         ff[index] += 1.0
         ii[index] -= 1
         index = numpy.where(ff > 0.5 )
         ff[index] -= 1.0
         ii[index] += 1
         return super(Phase, cls).__new__(cls, ii.to(u.cycle), ff.to(u.cycle))
Ejemplo n.º 37
0
    def __init__(self, wn, m, **kwargs):
        """
        CDESpectrum(wn, m, **kwargs)

        Constructor for the `CDESpectrum` class.

        Parameters
        ----------
        wn : `astropy.units.Quantity` or `numpy.ndarray`
            The absorption spectrum frequency data. If given as
            `astropy.units.Quantity`, they must either be in kayser (reciprocal
            wavenumbers) or convertable to kayser. If given as `numpy.ndarray`,
            they are assumed to be in kayser.
        m : `numpy.ndarray`
            The complex refractive index spectrum of the data.
        **kwargs : Arguments, optional
            Additional initialisation arguments can be passed to
            `AbsorptionSpectrum` using this. Note that x and y are defined
            using the other initialisation parameters of `CDESpectrum`.
        """
        if len(wn) != len(m):
            raise RuntimeError('Input arrays have different sizes.')
        if type(wn) != u.quantity.Quantity:
            wn = wn * u.kayser
        if wn.unit != u.kayser:
            with u.set_enabled_equivalencies(u.equivalencies.spectral()):
                wn = wn.to(u.kayser)
        self.cabs, self.cabs_vol, self.cscat_vol, self.ctot = \
            utils.cde_correct(wn.value, m)
        self.m = np.array(m, dtype=complex)
        od = self.cabs_vol * utils.unit_od
        AbsorptionSpectrum.__init__(self, wn, od, **kwargs)
Ejemplo n.º 38
0
    def test_raise_to_power(self, power):
        """Check that raising LogQuantities to some power is only possible when
        the physical unit is dimensionless, and that conversion is turned off
        when the resulting logarithmic unit (say, mag**2) is incompatible."""
        lq = u.Magnitude(np.arange(1., 4.) * u.Jy)

        if power == 0:
            assert np.all(lq**power == 1.)
        elif power == 1:
            assert np.all(lq**power == lq)
        else:
            with pytest.raises(u.UnitsError):
                lq**power

        # with dimensionless, it works, but falls back to normal quantity
        # (except for power=1)
        lq2 = u.Magnitude(np.arange(10.))

        t = lq2**power
        if power == 0:
            assert t.unit is u.dimensionless_unscaled
            assert np.all(t.value == 1.)
        elif power == 1:
            assert np.all(t == lq2)
        else:
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit**power
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(u.dimensionless_unscaled)
Ejemplo n.º 39
0
 def d_phase_d_GLTD(self, toas, param, delay):
     """Calculate the derivative wrt GLF0D
     """
     tbl = toas.table
     p, ids, idv = split_prefixed_name(param)
     if p != "GLTD_":
         raise ValueError(
             "Can not calculate d_phase_d_GLF0D with respect to %s." % param
         )
     eph = np.longdouble(getattr(self, "GLEP_" + ids).value)
     par_GLTD = getattr(self, param)
     if par_GLTD.value == 0.0:
         return np.zeros(len(tbl), dtype=np.longdouble) * u.cycle / par_GLTD.units
     glf0d = getattr(self, "GLF0D_" + ids).quantity
     tau = par_GLTD.quantity
     dt = (tbl["tdbld"] - eph) * u.day - delay
     dt = dt.to(u.second)
     affected = np.where(dt > 0.0)[0]
     dpdGLTD = np.zeros(len(tbl), dtype=np.longdouble) * u.cycle / par_GLTD.units
     with u.set_enabled_equivalencies(dimensionless_cycles):
         dpdGLTD[affected] += glf0d * (
             np.longdouble(1.0) - np.exp(-dt[affected] / tau)
         ) + glf0d * tau * (-np.exp(-dt[affected] / tau)) * dt[affected] / (
             tau * tau
         )
     return dpdGLTD
Ejemplo n.º 40
0
    def d_delayS_d_par(self,par):
        """dsDelay/dPar = dsDelay/dTM2*dTM2/dPar+
                          dsDelay/decc*decc/dPar+
                          dsDelay/dE*dE/dPar+
                          dsDelay/domega*domega/dPar+
                          dsDelay/dSINI*dSINI/dPar
        """
        e = self.ecc()
        cE = np.cos(self.E())
        sE = np.sin(self.E())
        sOmega = np.sin(self.omega())
        cOmega = np.cos(self.omega())
        TM2 = self.M2.value*Tsun

        logNum = 1-e*cE-self.SINI*(sOmega*(cE-e)+
                 (1-e**2)**0.5*cOmega*sE)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            dTM2_dpar = self.prtl_der('TM2',par)
            dsDelay_dTM2 = -2*np.log(logNum)
            decc_dpar = self.prtl_der('ecc',par)
            dsDelay_decc = -2*TM2/logNum*(-cE-self.SINI*(-e*cOmega*sE/np.sqrt(1-e**2)-sOmega))
            dE_dpar = self.prtl_der('E',par)
            dsDelay_dE =  -2*TM2/logNum*(e*sE-self.SINI*(np.sqrt(1-e**2)*cE*cOmega-sE*sOmega))
            domega_dpar = self.prtl_der('omega',par)
            dsDelay_domega = 2*TM2/logNum*self.SINI*((cE-e)*cOmega-np.sqrt(1-e**2)*sE*sOmega)
            dSINI_dpar = self.prtl_der('SINI',par)
            dsDelay_dSINI = -2*TM2/logNum*(-(1-e**2)**0.5*cOmega*sE-(cE-e)*sOmega)
            return dTM2_dpar*dsDelay_dTM2 + decc_dpar*dsDelay_decc + \
                   dE_dpar*dsDelay_dE +domega_dpar*dsDelay_domega +  \
                   dSINI_dpar*dsDelay_dSINI
Ejemplo n.º 41
0
def shklovskii_factor(pmtot: u.mas / u.yr, D: u.kpc):
    """Compute magnitude of Shklovskii correction factor.

    Computes the Shklovskii correction factor, as defined in Eq 8.12 of Lorimer & Kramer (2005) [10]_
    This is the factor by which :math:`\dot P /P` is increased due to the transverse velocity.
    Note that this affects both the measured spin period and the orbital period.
    If we call this Shklovskii acceleration :math:`a_s`, then

    .. math::

        \dot P_{\\rm intrinsic} = \dot P_{\\rm observed} - a_s P

    Parameters
    ----------
    pmtot : astropy.units.Quantity
        typically units of u.mas/u.yr
        Total proper motion of the pulsar :math:`\mu` (system)
    D : astropy.units.Quantity
        typically in units of u.kpc or u.pc
        Distance to the pulsar

    Returns
    -------
    acceleration : astropy.units.Quantity
        Shklovskii acceleration

    Notes
    -----
    .. [10] Lorimer & Kramer, 2008, "The Handbook of Pulsar Astronomy", Eqn. 8.12        
    """
    # This uses the small angle approximation that sin(x) = x, so we need to
    # make our angle dimensionless.
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        a_s = (D * pmtot**2 / const.c).to(u.s**-1)
    return a_s
Ejemplo n.º 42
0
    def d_delayI_d_par(self,par):
        """Derivative on delay inverse.
        """
        e = self.ecc()
        sE = np.sin(self.E())
        cE = np.cos(self.E())
        dE_dpar = self.prtl_der('E',par)
        decc_dpar = self.prtl_der('ecc',par)

        Dre = self.Dre()
        Drep = self.Drep()
        Drepp = self.Drepp()
        nHat = self.nhat()
        delayI = self.delayInverse()

        dDre_dpar = self.d_Dre_d_par(par)
        dDrep_dpar = self.d_Drep_d_par(par)
        dDrepp_dpar = self.d_Drepp_d_par(par)
        dnhat_dpar = self.d_nhat_d_par(par)
        oneMeccTcosE = (1-e*cE) # 1-e*cos(E)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            x =  -1.0/2.0*e*sE/oneMeccTcosE # -1/2*e*sin(E)/(1-e*cos(E))

            dx_dpar = -sE/(2*oneMeccTcosE**2)*decc_dpar+e*(e-cE)/(2*oneMeccTcosE**2)*dE_dpar

            diDelay_dDre = 1+(Drep*nHat)**2+Dre*Drepp*nHat**2+Drep*nHat*(2*Dre*nHat*x-1)
            diDelay_dDrep = Dre*nHat*(2*Drep*nHat+Dre*nHat*x-1)
            diDelay_dDrepp = (Dre*nHat)**2/2
            diDelay_dnhat = Dre*(-Drep+2*Drep**2*nHat+nHat*Dre*Drepp+2*x*nHat*Dre*Drep)
            diDelay_dx = (Dre*nHat)**2*Drep

            return dDre_dpar*diDelay_dDre + dDrep_dpar*diDelay_dDrep + \
                   dDrepp_dpar*diDelay_dDrepp + dx_dpar*diDelay_dx+ \
                   dnhat_dpar*diDelay_dnhat
Ejemplo n.º 43
0
    def d_Drep_d_par(self, par):
        """Derivative computation.

        Computes::

            Drep = d_Dre_d_Phi = a1/c.c*(cos(Phi) + eps1 * sin(Phi) + eps2 * cos(Phi))
            d_Drep_d_par = d_a1_d_par /c.c*(cos(Phi) + eps1 * sin(Phi) + eps2 * cos(Phi)) +
                          d_Drep_d_Phi * d_Phi_d_par + d_Drep_d_eps1*d_eps1_d_par +
                          d_Drep_d_eps2*d_eps2_d_par
        """
        a1 = self.a1()
        Phi = self.Phi()
        eps1 = self.eps1()
        eps2 = self.eps2()
        d_a1_d_par = self.prtl_der("a1", par)
        d_Drep_d_Phi = self.Drepp()
        d_Phi_d_par = self.prtl_der("Phi", par)
        d_Drep_d_eps1 = a1 / c.c * np.sin(2.0 * Phi)
        d_Drep_d_eps2 = a1 / c.c * np.cos(2.0 * Phi)

        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            d_Drep_d_par = (
                d_a1_d_par
                / c.c
                * (np.cos(Phi) + eps1 * np.sin(2.0 * Phi) + eps2 * np.cos(2.0 * Phi))
                + d_Drep_d_Phi * d_Phi_d_par
                + d_Drep_d_eps1 * self.prtl_der("eps1", par)
                + d_Drep_d_eps2 * self.prtl_der("eps2", par)
            )
        return d_Drep_d_par
Ejemplo n.º 44
0
 def __new__(cls, arg1, arg2=None):
     # Assume inputs are numerical, could add an extra
     # case to parse strings as input.
     # if it is not a list, convert to a list
     if not hasattr(arg1, 'unit'):
         arg1 = arg1 * u.cycle
     if arg1.shape == ():
         arg1 = arg1.reshape((1, ))
     with u.set_enabled_equivalencies(dimensionless_cycles):
         arg1 = arg1.to(u.Unit(""))
         # Since modf does not like dimensioned quantity
         if arg2 is None:
             ff, ii = numpy.modf(arg1)
         else:
             if not hasattr(arg2, 'unit'):
                 arg2 = arg2 * u.cycle
             if arg2.shape == ():
                 arg2 = arg2.reshape((1, ))
             arg2 = arg2.to(u.Unit(""))
             arg1S = numpy.modf(arg1)
             arg2S = numpy.modf(arg2)
             ii = arg1S[1] + arg2S[1]
             ff = arg2S[0]
         index = numpy.where(ff < -0.5)
         ff[index] += 1.0
         ii[index] -= 1
         index = numpy.where(ff > 0.5)
         ff[index] -= 1.0
         ii[index] += 1
         return super(Phase, cls).__new__(cls, ii.to(u.cycle),
                                          ff.to(u.cycle))
Ejemplo n.º 45
0
 def d_phase_d_jump(self, toas, jump_param, delay):
     tbl = toas.table
     jpar = getattr(self, jump_param)
     d_phase_d_j = numpy.zeros(len(tbl))
     mask = jpar.select_toa_mask(toas)
     d_phase_d_j[mask] = self.F0.value
     with u.set_enabled_equivalencies(dimensionless_cycles):
         return (d_phase_d_j * self.F0.units).to(u.cycle/u.second)
Ejemplo n.º 46
0
    def test_vgal_to_hel_single(self):

        # test a single entry
        row = self.data[0]
        c = coord.SkyCoord(ra=row['ra']*u.deg, dec=row['dec']*u.deg, distance=row['dist']*u.pc)
        pm = [row['pml'],row['pmb']]*u.mas/u.yr
        rv = row['rv']*u.km/u.s

        true_pmrv = (pm[0], pm[1], rv)
        vxyz = [row['U'],row['V'],row['W']]*u.km/u.s
        pmrv = vgal_to_hel(c.galactic, vxyz=vxyz,
                           vcirc=0.*u.km/u.s,
                           vlsr=[0.,0,0]*u.km/u.s)

        for i in range(3):
            np.testing.assert_allclose(pmrv[i].to(true_pmrv[i].unit).value,
                                       true_pmrv[i].value,
                                       atol=1.)

        # some sanity checks - first, some convenience definitions
        g = coord.Galactic(l=0*u.deg, b=0*u.deg).transform_to(coord.ICRS)
        frargs = dict(galcen_ra=g.ra,
                      galcen_dec=g.dec,
                      z_sun=0*u.kpc,
                      galcen_distance=8*u.kpc)
        galcen_frame = coord.Galactocentric(**frargs)

        # --------------------------------------------------------------------
        # l = 0
        # without LSR and circular velocity
        # c = coord.Galactocentric([6,0,0]*u.kpc,**frargs)
        c = coord.SkyCoord(l=0*u.deg, b=0*u.deg, distance=2*u.kpc, frame=coord.Galactic)
        vxyz = [20.,0,0]*u.km/u.s
        pmv = vgal_to_hel(c.galactic, vxyz,
                          vcirc=0*u.km/u.s,
                          vlsr=[0.,0,0]*u.km/u.s,
                          galactocentric_frame=galcen_frame)
        np.testing.assert_allclose(pmv[0].to(u.mas/u.yr).value, 0., atol=1E-12)
        np.testing.assert_allclose(pmv[1].to(u.mas/u.yr).value, 0., atol=1E-12)
        np.testing.assert_allclose(pmv[2].to(u.km/u.s).value, 20., atol=1E-12)

        # with LSR and circular velocity
        c = coord.SkyCoord(l=0*u.deg, b=0*u.deg, distance=2*u.kpc, frame=coord.Galactic)
        vxyz = [20.,0,0]*u.km/u.s
        pmv = vgal_to_hel(c.galactic, vxyz,
                          vcirc=-200*u.km/u.s,
                          vlsr=[0.,0,10]*u.km/u.s,
                          galactocentric_frame=galcen_frame)

        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            np.testing.assert_allclose(pmv[0].to(u.mas/u.yr).value,
                                       ((200.*u.km/u.s)/(2*u.kpc)).to(u.mas/u.yr).value,
                                       atol=1E-12)
            np.testing.assert_allclose(pmv[1].to(u.mas/u.yr).value,
                                       ((-10.*u.km/u.s)/(2*u.kpc)).to(u.mas/u.yr).value,
                                       atol=1E-4)
        np.testing.assert_allclose(pmv[2].to(u.km/u.s).value, 20., atol=1E-12)
Ejemplo n.º 47
0
def test_equivalency_context():
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        phase = u.Quantity(1., u.cycle)
        assert_allclose(np.exp(1j*phase), 1.)
        Omega = u.cycle / (1.*u.minute)
        assert_allclose(np.exp(1j*Omega*60.*u.second), 1.)
        # ensure we can turn off equivalencies even within the scope
        with pytest.raises(u.UnitsError):
            phase.to(1, equivalencies=None)

        # test the manager also works in the Quantity constructor.
        q1 = u.Quantity(phase, u.dimensionless_unscaled)
        assert_allclose(q1.value, u.cycle.to(u.radian))

        # and also if we use a class that happens to have a unit attribute.
        class MyQuantityLookalike(np.ndarray):
            pass

        mylookalike = np.array(1.).view(MyQuantityLookalike)
        mylookalike.unit = 'cycle'
        # test the manager also works in the Quantity constructor.
        q2 = u.Quantity(mylookalike, u.dimensionless_unscaled)
        assert_allclose(q2.value, u.cycle.to(u.radian))

    with u.set_enabled_equivalencies(u.spectral()):
        u.GHz.to(u.cm)
        eq_on = u.GHz.find_equivalent_units()
        with pytest.raises(u.UnitsError):
            u.GHz.to(u.cm, equivalencies=None)

    # without equivalencies, we should find a smaller (sub)set
    eq_off = u.GHz.find_equivalent_units()
    assert all(eq in set(eq_on) for eq in eq_off)
    assert set(eq_off) < set(eq_on)

    # Check the equivalency manager also works in ufunc evaluations,
    # not just using (wrong) scaling. [#2496]
    l2v = u.doppler_optical(6000 * u.angstrom)
    l1 = 6010 * u.angstrom
    assert l1.to(u.km/u.s, equivalencies=l2v) > 100. * u.km / u.s
    with u.set_enabled_equivalencies(l2v):
        assert l1 > 100. * u.km / u.s
        assert abs((l1 - 500. * u.km / u.s).to(u.angstrom)) < 1. * u.km/u.s
Ejemplo n.º 48
0
    def build_table(self):
        """
        Create a human readable table.

        Returns
        -------
        table : `astropy.table.QTable`
        """
        keywords = ['Start Time', 'End Time', 'Source', 'Instrument', 'Type', 'Wavelength']
        record_items = {}
        for key in keywords:
            record_items[key] = []

        def validate_time(time):
            # Handle if the time is None when coming back from VSO
            if time is None:
                return ['None']
            if record.time.start is not None:
                return [parse_time(time).strftime(TIME_FORMAT)]
            else:
                return ['N/A']

        for record in self:
            record_items['Start Time'].append(validate_time(record.time.start))
            record_items['End Time'].append(validate_time(record.time.end))
            record_items['Source'].append(str(record.source))
            record_items['Instrument'].append(str(record.instrument))
            record_items['Type'].append(str(record.extent.type)
                                        if record.extent.type is not None else ['N/A'])
            # If we have a start and end Wavelength, make a quantity
            if hasattr(record, 'wave') and record.wave.wavemin and record.wave.wavemax:
                unit = record.wave.waveunit
                # Convert this so astropy units parses it correctly
                if unit == "kev":
                    unit = "keV"
                record_items['Wavelength'].append(u.Quantity([float(record.wave.wavemin),
                                                              float(record.wave.wavemax)],
                                                             unit=unit))
            # If not save None
            else:
                record_items['Wavelength'].append(None)
        # If we have no wavelengths for the whole list, drop the col
        if all([a is None for a in record_items['Wavelength']]):
            record_items.pop('Wavelength')
            keywords.remove('Wavelength')
        else:
            # Make whole column a quantity
            try:
                with u.set_enabled_equivalencies(u.spectral()):
                    record_items['Wavelength'] = u.Quantity(record_items['Wavelength'])
            # If we have mixed units or some Nones just represent as strings
            except (u.UnitConversionError, TypeError):
                record_items['Wavelength'] = [str(a) for a in record_items['Wavelength']]

        return Table(record_items)[keywords]
Ejemplo n.º 49
0
 def quantity(self, qty):
     try:
         with set_enabled_equivalencies(self.equivalencies):
             self._value = qty.to(self.unit).value
     except AttributeError:
         if self.unit is dimensionless_unscaled or qty == 0:
             self._value = qty
         else:
             raise UnitsError("Can only assign dimensionless values "
                              "to dimensionless quantities "
                              "(unless the value is 0)")
Ejemplo n.º 50
0
    def __init__(self, wn, od, **kwargs):
        """
    AbsorptionSpectrum(wn,od,**kwargs)

    Constructor for the `AbsorptionSpectrum` class.

    Parameters
    ----------
    wn : `astropy.units.Quantity`
      The absorption spectrum frequency data. Unlike `BaseSpectrum`,
      the initialisation of `AbsorptionSpectrum` requires this to be
      in the specific units of reciprocal wavenumber. However, if it is
      in a quantity convertable to kayser, conversion will be attempted
      while a warning is given to notify the user of this.
    od : `astropy.units.Quantity`
      The absorption spectrum optical depth data. Unlike `BaseSpectrum`,
      the initialisation of `AbsorptionSpectrum` requires this to be
      in the specific units of optical depth units (from
      `omnifit.utils.unit_od`).
    **kwargs : Arguments, optional
      Additional initialisation arguments can be passed to `BaseSpectrum`
      using this. Note that x and y are defined using the other
      initialisation parameters of `AbsorptionSpectrum`.
    """
        if type(wn) != u.quantity.Quantity:
            raise u.UnitsError("Input wn is not an astropy quantity.")
        if wn.unit != u.kayser:
            warnings.warn("Input wn is not in kayser units. Converting...", RuntimeWarning)
            with u.set_enabled_equivalencies(u.equivalencies.spectral()):
                wn = wn.to(u.kayser)
        if type(od) != u.quantity.Quantity:
            raise u.UnitsError("Input od is not an astropy quantity.")
        if od.unit != utils.unit_od:
            raise u.UnitsError("Input od is not in optical depth units.")
        if len(wn) != len(od):
            raise RuntimeError("Input arrays have different sizes.")
        self.wn = wn
        with u.set_enabled_equivalencies(u.equivalencies.spectral()):
            self.wl = self.wn.to(u.micron)
        self.od = od
        BaseSpectrum.__init__(self, self.wn, self.od, **kwargs)
Ejemplo n.º 51
0
 def d_beta_d_EDOT(self):
     """dBeta/dEDOT = A1/c*((-(e+dtheta)/sqrt(1-(e+dtheta)**2)*cos(omega)*de/dEDOT- \
        (1-eTheta**2)**0.5*sin(omega)*domega/dEDOT
        de/dEDOT = tt0
     """
     eTheta = self.eTheta()
     a1 = (self.a1()).decompose()
     sinOmg = np.sin(self.omega())
     cosOmg = np.cos(self.omega())
     with u.set_enabled_equivalencies(u.dimensionless_angles()):
         return a1/c.c*((-eTheta)/np.sqrt(1-eTheta**2)*cosOmg*self.tt0- \
                (1-eTheta**2)**0.5*sinOmg*self.d_omega_d_par('EDOT'))
Ejemplo n.º 52
0
 def d_phase_d_F(self, toas, param, delay):
     """Calculate the derivative wrt to an spin term."""
     par = getattr(self, param)
     unit = par.units
     pn, idxf, idxv = split_prefixed_name(param)
     order = idxv + 1
     fterms = [0.0 * u.Unit("")] + self.get_spin_terms()
     # make the choosen fterms 1 others 0
     fterms = [ft * numpy.longdouble(0.0)/unit for ft in fterms]
     fterms[order] += numpy.longdouble(1.0)
     dt = self.get_dt(toas, delay)
     with u.set_enabled_equivalencies(dimensionless_cycles):
         d_pphs_d_f = taylor_horner(dt.to(u.second), fterms)
         return d_pphs_d_f.to(u.cycle/unit)
Ejemplo n.º 53
0
    def test_multiplication_division(self):
        """Check that multiplication/division with other quantities is only
        possible when the physical unit is dimensionless, and that this turns
        the result into a normal quantity."""
        lq = u.Magnitude(np.arange(1., 11.)*u.Jy)

        with pytest.raises(u.UnitsError):
            lq * (1.*u.m)

        with pytest.raises(u.UnitsError):
            (1.*u.m) * lq

        with pytest.raises(u.UnitsError):
            lq / lq

        for unit in (u.m, u.mag, u.dex):
            with pytest.raises(u.UnitsError):
                lq / unit

        lq2 = u.Magnitude(np.arange(1, 11.))

        with pytest.raises(u.UnitsError):
            lq2 * lq

        with pytest.raises(u.UnitsError):
            lq2 / lq

        with pytest.raises(u.UnitsError):
            lq / lq2

        # but dimensionless_unscaled can be cancelled
        r = lq2 / u.Magnitude(2.)
        assert r.unit == u.dimensionless_unscaled
        assert np.all(r.value == lq2.value/2.)

        # with dimensionless, normal units OK, but return normal quantities
        tf = lq2 * u.m
        tr = u.m * lq2
        for t in (tf, tr):
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit * u.m
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(lq2.unit.physical_unit)

        t = tf / (50.*u.cm)
        # now we essentially have the same quantity but with a prefactor of 2
        assert t.unit.is_equivalent(lq2.unit.function_unit)
        assert_allclose(t.to(lq2.unit.function_unit), lq2._function_view*2)
Ejemplo n.º 54
0
 def d_phase_d_GLF2(self, toas,  param, delay):
     """Calculate the derivative wrt GLF1"""
     tbl = toas.table
     p, ids, idv = split_prefixed_name(param)
     if p !=  'GLF2_':
         raise ValueError("Can not calculate d_phase_d_GLF2 with respect to %s." % param)
     eph = time_to_longdouble(getattr(self, "GLEP_" + ids).value)
     par_GLF2 = getattr(self, param)
     dt = (tbl['tdbld'] - eph) * u.day - delay
     dt = dt.to(u.second)
     affected = numpy.where(dt > 0.0)[0]
     dpdGLF2 = numpy.zeros(len(tbl), dtype=numpy.longdouble) * u.cycle/par_GLF2.units
     with u.set_enabled_equivalencies(dimensionless_cycles):
         dpdGLF2[affected] += numpy.longdouble(1.0)/6.0 * dt[affected] * dt[affected] * dt[affected]
     return dpdGLF2
Ejemplo n.º 55
0
    def spindown_phase(self, toas, delay):
        """Spindown phase function.

        delay is the time delay from the TOA to time of pulse emission
          at the pulsar, in seconds.

        This routine should implement Eq 120 of the Tempo2 Paper II (2006, MNRAS 372, 1549)

        returns an array of phases in long double
        """
        dt = self.get_dt(toas, delay)
        # Add the [0.0] because that is the constant phase term
        fterms = [0.0 * u.cycle] + self.get_spin_terms()
        with u.set_enabled_equivalencies(dimensionless_cycles):
            phs = taylor_horner(dt.to(u.second), fterms)
            return phs.to(u.cycle)
Ejemplo n.º 56
0
  def test_unitconversions(self):
    transmittance = 10.0
    absorbance = -np.log10(transmittance)
    opticaldepth = absorbance*np.log(10)
    transmittance *= utils.unit_transmittance
    absorbance *= utils.unit_absorbance
    opticaldepth *= utils.unit_opticaldepth
    with u.set_enabled_equivalencies(utils.equivalencies_absorption):
      assert absorbance.to(utils.unit_transmittance).value == transmittance.value
      assert absorbance.to(utils.unit_opticaldepth).value == opticaldepth.value

      assert transmittance.to(utils.unit_absorbance).value == absorbance.value
      assert transmittance.to(utils.unit_opticaldepth).value == opticaldepth.value

      assert opticaldepth.to(utils.unit_absorbance).value == absorbance.value
      assert opticaldepth.to(utils.unit_transmittance).value == transmittance.value
Ejemplo n.º 57
0
    def d_nhat_d_par(self,par):
        """nhat = n/(1-ecc*cos(E))
           n = 2*pi/PB # should here be M()?
           dnhat = -2*pi*dPB/PB^2*(1-ecc*cos(E))
                   -2*pi*(-cos(E)*decc+ecc*sin(E)*dE)/PB*(1-ecc*cos(E))^2

           dnhat/dPar = -2*pi/(PB*(1-ecc*cos(E))*((dPB/dPar)/PB -
                        (-cos(E)*decc/dPar+ecc*sin(E)*dE/dpar)/(1-e*cos(E)))
        """
        sinE = np.sin(self.E())
        cosE = np.cos(self.E())
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            oneMeccTcosE = (1-self.ecc()*cosE)
            fctr = -2*np.pi/self.pb()/oneMeccTcosE

            return fctr*(self.prtl_der('PB',par)/self.pb() - \
                   (cosE*self.prtl_der('ecc',par)- \
                    self.ecc()*sinE*self.prtl_der('E',par))/oneMeccTcosE)
Ejemplo n.º 58
0
    def convert2(self, newunit):
        """
    convert2(newunit,clone=False)

    Convert the x axis data to given spectral units.
    Re-sort the data afterwards.

    Parameters
    ----------
    newunit : `astropy.units.core.Unit`
      Desired (spectral) unit the x axis data should be
      converted to.
    clone : `bool`, optional
      If set to True, returns a modified copy of the spectrum instead
      of operating on the existing spectrum.
    """
        with u.set_enabled_equivalencies(u.equivalencies.spectral()):
            self.x = self.x.to(newunit)
        self.__sort()
Ejemplo n.º 59
0
 def test_kkiterfull(self):
   """
   Make sure that a longer KK iteration converges nicely
   """
   testspec = helpers.generate_absspectrum_alt()
   assert testspec.x.unit == u.kayser
   assert testspec.y.unit == utils.unit_od
   testspec.subspectrum(2000.,4500.)
   freq = testspec.x
   transmittance = testspec.y.to(utils.unit_transmittance,equivalencies=utils.equivalencies_absorption)
   m_substrate = 1.74+0.0j #CsI window, like in the original Hudgins paper
   d_ice = 1.0*u.micron #not probably true, but good enough for testing
   m0 = 1.3 + 0.0j
   with u.set_enabled_equivalencies(u.equivalencies.spectral()):
     freq_m0 = (0.15*u.micron).to(u.kayser).value
   m_ice = utils.kramers_kronig(freq,transmittance,m_substrate,d_ice,m0,freq_m0)
   assert m_ice.shape == freq.shape
   assert np.all(np.logical_not(np.isnan(m_ice.real)))
   assert np.all(np.logical_not(np.isnan(m_ice.imag)))
Ejemplo n.º 60
0
    def geostationary(
        cls, attractor, angular_velocity=None, period=None, hill_radius=None
    ):
        """Return the geostationary orbit for the given attractor and its rotational speed.

        Parameters
        ----------
        attractor : Body
            Main attractor.
        angular_velocity : ~astropy.units.Quantity
            Rotational angular velocity of the attractor.
        period : ~astropy.units.Quantity
            Attractor's rotational period, ignored if angular_velocity is passed.
        hill_radius : ~astropy.units.Quantity
            Radius of Hill sphere of the attractor (optional). Hill sphere radius(in
            contrast with Laplace's SOI) is used here to validate the stability of the
            geostationary orbit, that is to make sure that the orbital radius required
            for the geostationary orbit is not outside of the gravitational sphere of
            influence of the attractor.
            Hill SOI of parent(if exists) of the attractor is ignored if hill_radius is not provided.
        """

        if angular_velocity is None and period is None:
            raise ValueError(
                "At least one among angular_velocity or period must be passed"
            )

        if angular_velocity is None:
            angular_velocity = 2 * np.pi / period

        # Find out geostationary radius using r = cube_root(GM/(angular
        # velocity)^2)
        with u.set_enabled_equivalencies(u.dimensionless_angles()):
            geo_radius = np.cbrt(attractor.k / np.square(angular_velocity.to(1 / u.s)))

        if hill_radius is not None and geo_radius > hill_radius:
            raise ValueError(
                "Geostationary orbit for the given parameters doesn't exist"
            )

        altitude = geo_radius - attractor.R
        return cls.circular(attractor, altitude)