Ejemplo n.º 1
0
    def test_precision(self):
        """Set the output precision which is used for some formats.  This is
        also a test of the code that provides a dict for global and instance
        options."""

        t = Time("2010-01-01 00:00:00", format="iso", scale="utc")
        # Uses initial class-defined precision=3
        assert t.iso == "2010-01-01 00:00:00.000"

        # Set global precision = 5  XXX this uses private var, FIX THIS
        Time._precision = 5
        assert t.iso == "2010-01-01 00:00:00.00000"

        # Set instance precision to 9
        t.precision = 9
        assert t.iso == "2010-01-01 00:00:00.000000000"
        assert t.tai.utc.iso == "2010-01-01 00:00:00.000000000"

        # Restore global to original default of 3, instance is still at 9
        Time._precision = 3
        assert t.iso == "2010-01-01 00:00:00.000000000"

        # Make a new time instance and confirm precision = 3
        t = Time("2010-01-01 00:00:00", format="iso", scale="utc")
        assert t.iso == "2010-01-01 00:00:00.000"
Ejemplo n.º 2
0
    def _parse_hdus(cls, hdulist):
        header = MetaDict(OrderedDict(hdulist[0].header))
        # these GBM files have three FITS extensions.
        # extn1 - this gives the energy range for each of the 128 energy bins
        # extn2 - this contains the data, e.g. counts, exposure time, time of observation
        # extn3 - eclipse times?
        energy_bins = hdulist[1].data
        count_data = hdulist[2].data
        misc = hdulist[3].data

        # rebin the 128 energy channels into some summary ranges
        # 4-15 keV, 15 - 25 keV, 25-50 keV, 50-100 keV, 100-300 keV, 300-800 keV, 800 - 2000 keV
        # put the data in the units of counts/s/keV
        summary_counts = _bin_data_for_summary(energy_bins, count_data)

        # get the time information in datetime format with the correct MET adjustment
        gbm_times = Time([fermi.met_to_utc(t) for t in count_data['time']])
        gbm_times.precision = 9
        gbm_times = gbm_times.isot.astype('datetime64')

        column_labels = ['4-15 keV', '15-25 keV', '25-50 keV', '50-100 keV',
                         '100-300 keV', '300-800 keV', '800-2000 keV']

        # Add the units data
        units = OrderedDict([('4-15 keV', u.ct / u.s / u.keV), ('15-25 keV', u.ct / u.s / u.keV),
                             ('25-50 keV', u.ct / u.s / u.keV), ('50-100 keV', u.ct / u.s / u.keV),
                             ('100-300 keV', u.ct / u.s / u.keV), ('300-800 keV', u.ct / u.s / u.keV),
                             ('800-2000 keV', u.ct / u.s / u.keV)])
        return pd.DataFrame(summary_counts, columns=column_labels, index=gbm_times), header, units
Ejemplo n.º 3
0
def _get_time():
    t = Time([[1], [2]], format='cxcsec',
             location=EarthLocation(1000, 2000, 3000, unit=u.km))
    t.format = 'iso'
    t.precision = 5
    t.delta_ut1_utc = np.array([[3.0], [4.0]])
    t.delta_tdb_tt = np.array([[5.0], [6.0]])
    t.out_subfmt = 'date_hm'

    return t
Ejemplo n.º 4
0
def wcs_casa2astropy(coordsys):
    """
    Convert a casac.coordsys object into an astropy.wcs.WCS object
    """

    # Rather than try and parse the CASA coordsys ourselves, we delegate
    # to CASA by getting it to write out a FITS file and reading back in
    # using WCS

    header = fits.Header()

    # Observer information (ObsInfo.cc)

    header['OBSERVER'] = coordsys['observer']
    header['TELESCOP'] = coordsys['telescope']

    if coordsys['obsdate']['refer'] == 'LAST':

        header['TIMESYS'] = 'UTC'

    else:

        header['TIMESYS'] = coordsys['obsdate']['refer']
        header['MJD-OBS'] = coordsys['obsdate']['m0']['value']

        dateobs = Time(header['MJD-OBS'],
                       format='mjd',
                       scale=coordsys['obsdate']['refer'].lower())
        dateobs.precision = 6
        header['DATE-OBS'] = dateobs.isot

    if 'telescopeposition' in coordsys:

        obsgeo_lon = coordsys['telescopeposition']['m0']['value']
        obsgeo_lat = coordsys['telescopeposition']['m1']['value']
        obsgeo_alt = coordsys['telescopeposition']['m2']['value']

        header['OBSGEO-X'] = obsgeo_alt * np.cos(obsgeo_lon) * np.cos(
            obsgeo_lat)
        header['OBSGEO-Y'] = obsgeo_alt * np.sin(obsgeo_lon) * np.cos(
            obsgeo_lat)
        header['OBSGEO-Z'] = obsgeo_alt * np.sin(obsgeo_lat)

    # World coordinates

    # Find worldmap entries

    worldmap = {}

    for key, value in coordsys.items():
        if key.startswith('worldmap'):
            index = int(key[8:])
            worldmap[index] = value

    # Now iterate through the different coordinate types to populate the WCS

    header['WCSAXES'] = np.max([np.max(idx) + 1 for idx in worldmap.values()])

    # Initialize PC
    for ii in range(header['WCSAXES']):
        for jj in range(header['WCSAXES']):
            header[f'PC{ii+1}_{jj+1}'] = 0.

    for coord_type in ('direction', 'spectral', 'stokes', 'linear'):

        # Each coordinate type is stored with a numerical index,
        # so for example a cube might have direction0 and
        # spectral1, or spectral0, direction1, stokes2. The actual
        # index is irrelevant for the rest of the loop.
        for index in range(len(worldmap)):
            if f'{coord_type}{index}' in coordsys:
                data = coordsys[f'{coord_type}{index}']
                break
        else:
            # Skip the rest of the loop for the current coord_type
            # since the coord_type wasn't found with any index.
            continue

        if coord_type == 'direction':
            idx1, idx2 = worldmap[index] + 1
            header[f'CTYPE{idx1}'] = AXES_TO_CTYPE[data['system']][
                data['axes'][0]] + '-' + data['projection']
            header[f'CTYPE{idx2}'] = AXES_TO_CTYPE[data['system']][
                data['axes'][1]] + '-' + data['projection']
            header[f'CRPIX{idx1}'] = data['crpix'][0] + 1
            header[f'CRPIX{idx2}'] = data['crpix'][1] + 1
            header[f'CRVAL{idx1}'] = data['crval'][0]
            header[f'CRVAL{idx2}'] = data['crval'][1]
            header[f'CDELT{idx1}'] = data['cdelt'][0]
            header[f'CDELT{idx2}'] = data['cdelt'][1]
            header[f'CUNIT{idx1}'] = sanitize_unit(data['units'][0])
            header[f'CUNIT{idx2}'] = sanitize_unit(data['units'][1])
            header['LONPOLE'] = data['longpole']
            header['LATPOLE'] = data['latpole']
            if data.get('system') in EQUATORIAL_SYSTEMS:
                header['RADESYS'] = RADESYS[data['conversionSystem']]
                if data['conversionSystem'] in EQUINOX:
                    header['EQUINOX'] = EQUINOX[data['conversionSystem']]
            # NOTE: unclear if it is deliberate that the following is always
            # ?_2 and ?_1 or whether it should depend on the index of the
            # longitude.
            if data.get('system') in EQUATORIAL_SYSTEMS:
                header[f'PV{idx2}_1'] = 0.
                header[f'PV{idx2}_2'] = 0.
            header[f'PC{idx1}_{idx1}'] = data['pc'][0, 0]
            header[f'PC{idx1}_{idx2}'] = data['pc'][0, 1]
            header[f'PC{idx2}_{idx1}'] = data['pc'][1, 0]
            header[f'PC{idx2}_{idx2}'] = data['pc'][1, 1]
        elif coord_type == 'stokes':
            idx = worldmap[index][0] + 1
            header[f'CTYPE{idx}'] = 'STOKES'
            header[f'CRVAL{idx}'] = data['crval'][0]
            header[f'CRPIX{idx}'] = data['crpix'][0] + 1
            header[f'CDELT{idx}'] = data['cdelt'][0]
            header[f'CUNIT{idx}'] = ''
            header[f'PC{idx}_{idx}'] = data['pc'][0][0]
        elif coord_type == 'spectral':
            idx = worldmap[index][0] + 1
            if 'tabular' in data:
                header[f'CTYPE{idx}'] = AXES_TO_CTYPE[data['tabular']['axes']
                                                      [0]]
                header[f'CRVAL{idx}'] = data['tabular']['crval'][0]
                header[f'CRPIX{idx}'] = data['tabular']['crpix'][0] + 1
                # It looks like we can't just use:
                # header[f'CDELT{idx}'] = data['tabular']['cdelt'][0]
                # because this doesn't match what appears in a FITS header
                # exported from CASA. Instead we use the interval between the
                # first two tabulated values. See
                # https://github.com/radio-astro-tools/spectral-cube/issues/614
                # for more information.
                header[f'CDELT{idx}'] = np.diff(
                    data['tabular']['worldvalues'][:2])[0]
                header[f'CUNIT{idx}'] = data['tabular']['units'][0]
            else:
                header[f'CTYPE{idx}'] = data['wcs']['ctype']
                header[f'CRVAL{idx}'] = data['wcs']['crval']
                header[f'CRPIX{idx}'] = data['wcs']['crpix'] + 1
                header[f'CDELT{idx}'] = data['wcs']['cdelt']
                header[f'CUNIT{idx}'] = data['unit']
            header[f'PC{idx}_{idx}'] = 1.0
            header[f'RESTFRQ'] = data['restfreq']
            if data['system'] in SPECSYS:
                header[f'SPECSYS'] = SPECSYS[data['system']]
        elif coord_type == 'linear':
            indices = worldmap[index] + 1
            for idx1 in range(len(indices)):
                header[f'CTYPE{indices[idx1]}'] = data['axes'][idx1].upper()
                header[f'CRVAL{indices[idx1]}'] = data['crval'][idx1]
                header[f'CRPIX{indices[idx1]}'] = data['crpix'][idx1] + 1
                header[f'CDELT{indices[idx1]}'] = data['cdelt'][idx1]
                header[f'CUNIT{indices[idx1]}'] = data['units'][idx1]
                for idx2 in range(len(indices)):
                    header[f'PC{indices[idx1]}_{indices[idx1]}'] = data['pc'][
                        idx1, idx1]
                    header[f'PC{indices[idx1]}_{indices[idx2]}'] = data['pc'][
                        idx1, idx2]
                    header[f'PC{indices[idx2]}_{indices[idx1]}'] = data['pc'][
                        idx2, idx1]
                    header[f'PC{indices[idx2]}_{indices[idx2]}'] = data['pc'][
                        idx2, idx2]
        else:
            raise NotImplementedError(f'coord_type is {coord_type}')

    return WCS(header)