Example #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()
Example #2
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)
Example #3
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)
Example #4
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]
    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.)))
Example #6
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)
Example #7
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
Example #8
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
Example #9
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)
Example #10
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)
Example #11
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))
Example #12
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)
    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)
Example #14
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)
Example #15
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)
Example #16
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)
Example #17
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
Example #18
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]
Example #19
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)")
Example #20
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)
Example #21
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'))
Example #22
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)
    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)
Example #24
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
Example #25
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)
Example #26
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
Example #27
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)
Example #28
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)))
Example #29
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()
Example #30
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)