Exemple #1
0
def test_erfa_wrapper():
    """
    Runs a set of tests that mostly make sure vectorization is
    working as expected
    """

    jd = np.linspace(2456855.5, 2456855.5+1.0/24.0/60.0, 60*2+1)
    ra = np.linspace(0.0, np.pi*2.0, 5)
    dec = np.linspace(-np.pi/2.0, np.pi/2.0, 4)

    aob, zob, hob, dob, rob, eo = erfa.atco13(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, jd, 0.0, 0.0, 0.0, np.pi/4.0, 0.0, 0.0, 0.0, 1014.0, 0.0, 0.0, 0.5)
    assert aob.shape == (121,)

    aob, zob, hob, dob, rob, eo = erfa.atco13(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, jd[0], 0.0, 0.0, 0.0, np.pi/4.0, 0.0, 0.0, 0.0, 1014.0, 0.0, 0.0, 0.5)
    assert aob.shape == ()

    aob, zob, hob, dob, rob, eo = erfa.atco13(ra[:, None, None], dec[None, :, None], 0.0, 0.0, 0.0, 0.0, jd[None, None, :], 0.0, 0.0, 0.0, np.pi/4.0, 0.0, 0.0, 0.0, 1014.0, 0.0, 0.0, 0.5)
    (aob.shape) == (5, 4, 121)

    iy, im, id, ihmsf = erfa.d2dtf("UTC", 3, jd, 0.0)
    assert iy.shape == (121,)
    assert ihmsf.shape == (121,)
    assert ihmsf.dtype == erfa.dt_hmsf

    iy, im, id, ihmsf = erfa.d2dtf("UTC", 3, jd[0], 0.0)
    assert iy.shape == ()
    assert ihmsf.shape == ()
    assert ihmsf.dtype == erfa.dt_hmsf
    def to_value(self, timezone=None, parent=None):
        """
        Convert to (potentially timezone-aware) `~datetime.datetime` object.

        If ``timezone`` is not ``None``, return a timezone-aware datetime
        object.

        Parameters
        ----------
        timezone : {`~datetime.tzinfo`, None} (optional)
            If not `None`, return timezone-aware datetime.

        Returns
        -------
        `~datetime.datetime`
            If ``timezone`` is not ``None``, output will be timezone-aware.
        """
        if timezone is not None:
            if self._scale != 'utc':
                raise ScaleValueError(
                    "scale is {}, must be 'utc' when timezone "
                    "is supplied.".format(self._scale))

        # Rather than define a value property directly, we have a function,
        # since we want to be able to pass in timezone information.
        scale = self.scale.upper().encode('ascii')
        iys, ims, ids, ihmsfs = erfa.d2dtf(
            scale,
            6,  # 6 for microsec
            self.jd1,
            self.jd2_filled)
        ihrs = ihmsfs['h']
        imins = ihmsfs['m']
        isecs = ihmsfs['s']
        ifracs = ihmsfs['f']
        iterator = np.nditer([iys, ims, ids, ihrs, imins, isecs, ifracs, None],
                             flags=['refs_ok'],
                             op_dtypes=7 * [iys.dtype] + [object])

        for iy, im, id, ihr, imin, isec, ifracsec, out in iterator:
            if isec >= 60:
                raise ValueError(
                    'Time {} is within a leap second but datetime '
                    'does not support leap seconds'.format(
                        (iy, im, id, ihr, imin, isec, ifracsec)))
            if timezone is not None:
                out[...] = datetime.datetime(
                    iy,
                    im,
                    id,
                    ihr,
                    imin,
                    isec,
                    ifracsec,
                    tzinfo=TimezoneInfo()).astimezone(timezone)
            else:
                out[...] = datetime.datetime(iy, im, id, ihr, imin, isec,
                                             ifracsec)

        return self.mask_if_needed(iterator.operands[-1])
    def value(self):
        scale = self.scale.upper().encode('ascii')
        iy_start, ims, ids, ihmsfs = erfa.d2dtf(
            scale,
            0,  # precision=0
            self.jd1,
            self.jd2_filled)
        imon = np.ones_like(iy_start)
        iday = np.ones_like(iy_start)
        ihr = np.zeros_like(iy_start)
        imin = np.zeros_like(iy_start)
        isec = np.zeros_like(self.jd1)

        # Possible enhancement: use np.unique to only compute start, stop
        # for unique values of iy_start.
        scale = self.scale.upper().encode('ascii')
        jd1_start, jd2_start = erfa.dtf2d(scale, iy_start, imon, iday, ihr,
                                          imin, isec)
        jd1_end, jd2_end = erfa.dtf2d(scale, iy_start + 1, imon, iday, ihr,
                                      imin, isec)

        dt = (self.jd1 - jd1_start) + (self.jd2 - jd2_start)
        dt_end = (jd1_end - jd1_start) + (jd2_end - jd2_start)
        decimalyear = iy_start + dt / dt_end

        return decimalyear
Exemple #4
0
    def str_kwargs(self):
        """
        Generator that yields a dict of values corresponding to the
        calendar date and time for the internal JD values.
        """
        iys, ims, ids, ihmsfs = d2dtf(self.scale.upper()
                                      .encode('utf8'),
                                      6,
                                      self.jd1, self.jd2)

        # Get the str_fmt element of the first allowed output subformat
        _, _, str_fmt = self._select_subfmts(self.out_subfmt)[0]

        yday = None
        has_yday = '{yday:' in str_fmt or False

        ihrs = ihmsfs[..., 0]
        imins = ihmsfs[..., 1]
        isecs = ihmsfs[..., 2]
        ifracs = ihmsfs[..., 3]
        for iy, im, iday, ihr, imin, isec, ifracsec in numpy.nditer(
                [iys, ims, ids, ihrs, imins, isecs, ifracs]):
            if has_yday:
                yday = datetime(iy, im, iday).timetuple().tm_yday

            fracday = (((((ifracsec / 1000000.0 + isec) / 60.0 + imin) / 60.0) + ihr) / 24.0) * (10 ** 6)
            fracday = '{0:06g}'.format(fracday)[0:self.precision]

            yield {'year': int(iy), 'mon': int(im), 'day': int(iday),
                   'hour': int(ihr), 'min': int(imin), 'sec': int(isec),
                   'fracsec': int(ifracsec), 'yday': yday, 'fracday': fracday}
Exemple #5
0
    def str_kwargs(self):
        """
        Generator that yields a dict of values corresponding to the
        calendar date and time for the internal JD values.
        """
        iys, ims, ids, ihmsfs = d2dtf(self.scale.upper()
                                      .encode('utf8'),
                                      6,
                                      self.jd1, self.jd2)

        # Get the str_fmt element of the first allowed output subformat
        _, _, str_fmt = self._select_subfmts(self.out_subfmt)[0]

        yday = None
        has_yday = '{yday:' in str_fmt or False

        ihrs = ihmsfs[..., 0]
        imins = ihmsfs[..., 1]
        isecs = ihmsfs[..., 2]
        ifracs = ihmsfs[..., 3]
        for iy, im, iday, ihr, imin, isec, ifracsec in numpy.nditer(
                [iys, ims, ids, ihrs, imins, isecs, ifracs]):
            if has_yday:
                yday = datetime(iy, im, iday).timetuple().tm_yday

            fracday = (((((ifracsec / 1000000.0 + isec) / 60.0 + imin) / 60.0) + ihr) / 24.0) * (10 ** 6)
            fracday = '{0:06g}'.format(fracday)[0:self.precision]

            yield {'year': int(iy), 'mon': int(im), 'day': int(iday),
                   'hour': int(ihr), 'min': int(imin), 'sec': int(isec),
                   'fracsec': int(ifracsec), 'yday': yday, 'fracday': fracday}
Exemple #6
0
    def str_kwargs(self):
        """
        Generator that yields a dict of values corresponding to the
        calendar date and time for the internal JD values.
        """
        scale = self.scale.upper().encode('ascii'),
        iys, ims, ids, ihmsfs = erfa.d2dtf(scale, self.precision,
                                           self.jd1, self.jd2_filled)

        # Get the str_fmt element of the first allowed output subformat
        _, _, str_fmt = self._select_subfmts(self.out_subfmt)[0]

        if '{yday:' in str_fmt:
            has_yday = True
        else:
            has_yday = False
            yday = None

        ihrs = ihmsfs['h']
        imins = ihmsfs['m']
        isecs = ihmsfs['s']
        ifracs = ihmsfs['f']
        for iy, im, id, ihr, imin, isec, ifracsec in np.nditer(
                [iys, ims, ids, ihrs, imins, isecs, ifracs]):
            if has_yday:
                yday = datetime.datetime(iy, im, id).timetuple().tm_yday

            yield {'year': int(iy), 'mon': int(im), 'day': int(id),
                   'hour': int(ihr), 'min': int(imin), 'sec': int(isec),
                   'fracsec': int(ifracsec), 'yday': yday}
Exemple #7
0
    def str_kwargs(self):
        """
        Generator that yields a dict of values corresponding to the
        calendar date and time for the internal JD values.
        """
        scale = self.scale.upper().encode('ascii'),
        iys, ims, ids, ihmsfs = erfa.d2dtf(scale, self.precision,
                                           self.jd1, self.jd2_filled)

        # Get the str_fmt element of the first allowed output subformat
        _, _, str_fmt = self._select_subfmts(self.out_subfmt)[0]

        if '{yday:' in str_fmt:
            has_yday = True
        else:
            has_yday = False
            yday = None

        ihrs = ihmsfs['h']
        imins = ihmsfs['m']
        isecs = ihmsfs['s']
        ifracs = ihmsfs['f']
        for iy, im, id, ihr, imin, isec, ifracsec in np.nditer(
                [iys, ims, ids, ihrs, imins, isecs, ifracs],
                flags=['zerosize_ok']):
            if has_yday:
                yday = datetime.datetime(iy, im, id).timetuple().tm_yday

            yield {'year': int(iy), 'mon': int(im), 'day': int(id),
                   'hour': int(ihr), 'min': int(imin), 'sec': int(isec),
                   'fracsec': int(ifracsec), 'yday': yday}
Exemple #8
0
    def to_value(self, timezone=None, parent=None):
        """
        Convert to (potentially timezone-aware) `~datetime.datetime` object.

        If ``timezone`` is not ``None``, return a timezone-aware datetime
        object.

        Parameters
        ----------
        timezone : {`~datetime.tzinfo`, None} (optional)
            If not `None`, return timezone-aware datetime.

        Returns
        -------
        `~datetime.datetime`
            If ``timezone`` is not ``None``, output will be timezone-aware.
        """
        if timezone is not None:
            if self._scale != 'utc':
                raise ScaleValueError("scale is {}, must be 'utc' when timezone "
                                      "is supplied.".format(self._scale))

        # Rather than define a value property directly, we have a function,
        # since we want to be able to pass in timezone information.
        scale = self.scale.upper().encode('ascii')
        iys, ims, ids, ihmsfs = erfa.d2dtf(scale, 6,  # 6 for microsec
                                           self.jd1, self.jd2_filled)
        ihrs = ihmsfs['h']
        imins = ihmsfs['m']
        isecs = ihmsfs['s']
        ifracs = ihmsfs['f']
        iterator = np.nditer([iys, ims, ids, ihrs, imins, isecs, ifracs, None],
                             flags=['refs_ok'],
                             op_dtypes=7*[iys.dtype] + [object])

        for iy, im, id, ihr, imin, isec, ifracsec, out in iterator:
            if isec >= 60:
                raise ValueError('Time {} is within a leap second but datetime '
                                 'does not support leap seconds'
                                 .format((iy, im, id, ihr, imin, isec, ifracsec)))
            if timezone is not None:
                out[...] = datetime.datetime(iy, im, id, ihr, imin, isec, ifracsec,
                                             tzinfo=TimezoneInfo()).astimezone(timezone)
            else:
                out[...] = datetime.datetime(iy, im, id, ihr, imin, isec, ifracsec)

        return self.mask_if_needed(iterator.operands[-1])
Exemple #9
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during 
         # leap seconds, so raise an exception in that 
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC',9,self.jd1,self.jd2)
         if 60 in hmsf[...,2]:
             raise ValueError('UTC times during a leap second cannot be represented in pulsar_mjd format')
         j1, j2 = erfa.cal2jd(y,mo,d)
         return (j1 - erfa.DJM0 + j2) + (hmsf[...,0]/24.0 
                 + hmsf[...,1]/1440.0 
                 + hmsf[...,2]/86400.0 
                 + hmsf[...,3]/86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
Exemple #10
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during
         # leap seconds, so raise an exception in that
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC', 9, self.jd1, self.jd2)
         if 60 in hmsf[..., 2]:
             raise ValueError(
                 'UTC times during a leap second cannot be represented in pulsar_mjd format'
             )
         j1, j2 = erfa.cal2jd(y, mo, d)
         return (j1 - erfa.DJM0 +
                 j2) + (hmsf[..., 0] / 24.0 + hmsf[..., 1] / 1440.0 +
                        hmsf[..., 2] / 86400.0 + hmsf[..., 3] / 86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
Exemple #11
0
    def to_value(self, parent=None):
        scale = self.scale.upper().encode('ascii'),
        iys, ims, ids, ihmsfs = erfa.d2dtf(scale, self.precision,
                                           self.jd1, self.jd2)
        ihrs = ihmsfs[..., 0]
        imins = ihmsfs[..., 1]
        isecs = ihmsfs[..., 2]
        ifracs = ihmsfs[..., 3]

        fmt = ('{0:04d} {1:02d} {2:02d} {3:02d} {4:02d} {5:02d} 0.{6:0' +
               str(self.precision) + 'd}')
        outs = []
        for iy, im, id, ihr, imin, isec, ifracsec in np.nditer(
                [iys, ims, ids, ihrs, imins, isecs, ifracs]):
            outs.append(fmt.format(int(iy), int(im), int(id), int(ihr),
                                   int(imin), int(isec), int(ifracsec)))

        return np.array(outs).reshape(self.jd1.shape)
Exemple #12
0
    def to_value(self, parent=None):
        scale = self.scale.upper().encode('ascii'),
        iys, ims, ids, ihmsfs = erfa.d2dtf(scale, self.precision, self.jd1,
                                           self.jd2)
        ihrs = ihmsfs[..., 0]
        imins = ihmsfs[..., 1]
        isecs = ihmsfs[..., 2]
        ifracs = ihmsfs[..., 3]

        fmt = ('{0:04d} {1:02d} {2:02d} {3:02d} {4:02d} {5:02d} 0.{6:0' +
               str(self.precision) + 'd}')
        outs = []
        for iy, im, id, ihr, imin, isec, ifracsec in np.nditer(
            [iys, ims, ids, ihrs, imins, isecs, ifracs]):
            outs.append(
                fmt.format(int(iy), int(im), int(id), int(ihr), int(imin),
                           int(isec), int(ifracsec)))

        return np.array(outs).reshape(self.jd1.shape)
Exemple #13
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during
         # leap seconds, so raise an exception in that
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC',9,self.jd1,self.jd2)
         # For ASTROPY_LT_3_1, convert to the new structured array dtype that
         # is returned by the new erfa gufuncs.
         if not hmsf.dtype.names:
             hmsf = hmsf.view(self._new_ihmsfs_dtype)
         if numpy.any(hmsf['s'] == 60):
             raise ValueError('UTC times during a leap second cannot be represented in pulsar_mjd format')
         j1, j2 = erfa.cal2jd(y,mo,d)
         return (j1 - erfa.DJM0 + j2) + (hmsf['h']/24.0
                 + hmsf['m']/1440.0
                 + hmsf['s']/86400.0
                 + hmsf['f']/86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
Exemple #14
0
 def value(self):
     if self._scale == 'utc':
         # Do the reverse of the above calculation
         # Note this will return an incorrect value during
         # leap seconds, so raise an exception in that
         # case.
         y, mo, d, hmsf = erfa.d2dtf('UTC',9,self.jd1,self.jd2)
         # For ASTROPY_LT_3_1, convert to the new structured array dtype that
         # is returned by the new erfa gufuncs.
         if not hmsf.dtype.names:
             hmsf = hmsf.view(self._new_ihmsfs_dtype)
         if numpy.any(hmsf['s'] == 60):
             raise ValueError('UTC times during a leap second cannot be represented in pulsar_mjd format')
         j1, j2 = erfa.cal2jd(y,mo,d)
         return (j1 - erfa.DJM0 + j2) + (hmsf['h']/24.0
                 + hmsf['m']/1440.0
                 + hmsf['s']/86400.0
                 + hmsf['f']/86400.0e9)
     else:
         # As in TimeMJD
         return (self.jd1 - erfa.DJM0) + self.jd2
Exemple #15
0
    def to_value(self, parent=None):
        scale = self.scale.upper().encode('ascii'),
        iys, ims, ids, ihmsfs = erfa.d2dtf(scale, self.precision,
                                           self.jd1, self.jd2)
        # For ASTROPY_LT_3_1, convert to the new structured array dtype that is
        # returned by the new erfa gufuncs.
        if not ihmsfs.dtype.names:
            ihmsfs = ihmsfs.view(self._new_ihmsfs_dtype)
        ihrs = ihmsfs['h']
        imins = ihmsfs['m']
        isecs = ihmsfs['s']
        ifracs = ihmsfs['f']

        fmt = ('{0:04d} {1:02d} {2:02d} {3:02d} {4:02d} {5:02d} 0.{6:0' +
               str(self.precision) + 'd}')
        outs = []
        for iy, im, id, ihr, imin, isec, ifracsec in np.nditer(
                [iys, ims, ids, ihrs, imins, isecs, ifracs]):
            outs.append(fmt.format(int(iy), int(im), int(id), int(ihr),
                                   int(imin), int(isec), int(ifracsec)))

        return np.array(outs).reshape(self.jd1.shape)
Exemple #16
0
def jds_to_mjds_pulsar(jd1, jd2):
    # Do the reverse of the above calculation
    # Note this will return an incorrect value during
    # leap seconds, so raise an exception in that
    # case.
    y, mo, d, hmsf = erfa.d2dtf("UTC", _digits, jd1, jd2)
    # For ASTROPY_LT_3_1, convert to the new structured array dtype that
    # is returned by the new erfa gufuncs.
    if not hmsf.dtype.names:
        hmsf = hmsf.view(_new_ihmsfs_dtype)[..., 0]
    if np.any((hmsf["s"] == 60) & (hmsf["f"] != 0)):
        # if f is exactly zero, this is probably fine to treat as the end of the day.
        raise ValueError(
            "UTC times during a leap second cannot be represented in pulsar_mjd format"
        )
    j1, j2 = erfa.cal2jd(y, mo, d)
    return day_frac(
        j1 - erfa.DJM0 + j2,
        hmsf["h"] / 24.0
        + hmsf["m"] / 1440.0
        + hmsf["s"] / 86400.0
        + hmsf["f"] / 86400.0 / 10 ** _digits,
    )
Exemple #17
0
    def value(self):
        scale = self.scale.upper().encode('ascii')
        iy_start, ims, ids, ihmsfs = erfa.d2dtf(scale, 0,  # precision=0
                                                self.jd1, self.jd2_filled)
        imon = np.ones_like(iy_start)
        iday = np.ones_like(iy_start)
        ihr = np.zeros_like(iy_start)
        imin = np.zeros_like(iy_start)
        isec = np.zeros_like(self.jd1)

        # Possible enhancement: use np.unique to only compute start, stop
        # for unique values of iy_start.
        scale = self.scale.upper().encode('ascii')
        jd1_start, jd2_start = erfa.dtf2d(scale, iy_start, imon, iday,
                                          ihr, imin, isec)
        jd1_end, jd2_end = erfa.dtf2d(scale, iy_start + 1, imon, iday,
                                      ihr, imin, isec)

        dt = (self.jd1 - jd1_start) + (self.jd2 - jd2_start)
        dt_end = (jd1_end - jd1_start) + (jd2_end - jd2_start)
        decimalyear = iy_start + dt / dt_end

        return decimalyear