Esempio n. 1
0
    def test_function(self):
        # Polarization function is None, should not produce an error
        axis = Axis("STOKES", "cunit")
        axis_1d = CoordAxis1D(axis)
        polarization = PolarizationWCS(axis_1d)
        wcsvalidator._validate_polarization_wcs(polarization)

        # Polarization axis function with naxis=1
        naxis = int(1)
        delta = float(2.5)
        ref_coord = wcs.RefCoord(float(1.0), float(2.0))
        axis_1d.function = CoordFunction1D(naxis, delta, ref_coord)
        polarization = PolarizationWCS(axis_1d)
        wcsvalidator._validate_polarization_wcs(polarization)

        # Polarization axis function with naxis>1
        naxis = int(3)
        delta = float(2.5)
        ref_coord = wcs.RefCoord(float(1.0), float(2.0))
        axis_1d.function = CoordFunction1D(naxis, delta, ref_coord)
        polarization = PolarizationWCS(axis_1d)
        wcsvalidator._validate_polarization_wcs(polarization)

        # Polarization axis function with invalid naxis=0
        naxis = int(0)
        delta = float(2.5)
        ref_coord = wcs.RefCoord(float(1.0), float(2.0))
        axis_1d.function = CoordFunction1D(naxis, delta, ref_coord)
        polarization = PolarizationWCS(axis_1d)
        with pytest.raises(InvalidWCSError) as ex:
            wcsvalidator._validate_polarization_wcs(polarization)
        assert ('Invalid Polarization WCS' in str(ex.value))
        assert ('Invalid naxis value' in str(ex.value))
Esempio n. 2
0
 def get_test_function_with_function(ctype, unit, px, sx, nx, ds):
     error = None
     range = None
     bounds = None
     naxis = int(1)
     delta = float(2.5)
     ref_coord = wcs.RefCoord(float(1.0), float(2.0))
     function = CoordFunction1D(naxis, delta, ref_coord)
     axis_1d = CoordAxis1D(wcs.Axis(ctype, unit), error, range, bounds,
                           function)
     ref_coord = RefCoord(px, sx)
     axis_1d.function = CoordFunction1D(nx, ds, ref_coord)
     custom_wcs = chunk.CustomWCS(axis_1d)
     return custom_wcs
Esempio n. 3
0
def build_chunk_time(chunk, header, name):
    """

    :param chunk: CAOM2 Chunk instance for which to set time.
    :param header: FITS header with the keywords for value extraction.
    :param name: str  for logging information only.
    :return:
    """
    logging.debug(f'Begin build_chunk_time for {name}.')
    # DB 02-07-20
    # time metadata comes from MJD_OBS and EXPTIME, it's not
    # an axis requiring cutout support
    exp_time = header.get('EXPTIME')
    mjd_obs = header.get('MJD-OBS')
    if exp_time is None or mjd_obs is None:
        chunk.time = None
    else:
        if chunk.time is None:
            coord_error = CoordError(syser=1e-07, rnder=1e-07)
            time_axis = CoordAxis1D(axis=Axis('TIME', 'd'), error=coord_error)
            chunk.time = TemporalWCS(axis=time_axis, timesys='UTC')
        ref_coord = RefCoord(pix=0.5, val=mjd_obs)
        chunk.time.axis.function = CoordFunction1D(
            naxis=1, delta=mc.convert_to_days(exp_time), ref_coord=ref_coord)
        chunk.time.exposure = exp_time
        chunk.time.resolution = mc.convert_to_days(exp_time)
    logging.debug(f'End build_chunk_time.')
Esempio n. 4
0
    def bad_delta():
        axis_1d = CoordAxis1D(wcs.Axis("RM", "rad/m**2"))
        # delta < 0.0 is bad
        ref_coord = RefCoord(float(1.0), float(2.0))
        axis_1d.function = CoordFunction1D(int(100), -0.01, ref_coord)

        return chunk.CustomWCS(axis_1d)
Esempio n. 5
0
def _update_time(chunk, headers):
    """Create TemporalWCS information using FITS header information.
    This information should always be available from the file."""
    logging.debug('Begin _update_time.')
    mc.check_param(chunk, Chunk)

    mjd_start = headers[0].get('MJD_STAR')
    mjd_end = headers[0].get('MJD_END')
    if mjd_start is None or mjd_end is None:
        mjd_start, mjd_end = ac.find_time_bounds(headers)
    if mjd_start is None or mjd_end is None:
        chunk.time = None
        logging.debug('Cannot calculate mjd_start {} or mjd_end {}'.format(
            mjd_start, mjd_end))
    else:
        logging.debug('Calculating range with start {} and end {}.'.format(
            mjd_start, mjd_start))
        start = RefCoord(0.5, mjd_start)
        end = RefCoord(1.5, mjd_end)
        time_cf = CoordFunction1D(1, headers[0].get('TEFF'), start)
        time_axis = CoordAxis1D(Axis('TIME', 'd'), function=time_cf)
        time_axis.range = CoordRange1D(start, end)
        chunk.time = TemporalWCS(time_axis)
        chunk.time.exposure = headers[0].get('TEFF')
        chunk.time.resolution = 0.1
        chunk.time.timesys = 'UTC'
        chunk.time.trefpos = 'TOPOCENTER'
        chunk.time_axis = 4
    logging.debug('Done _update_time.')
Esempio n. 6
0
def _update_energy(chunk, header, filter_name, obs_id):
    logging.debug(f'Begin _update_energy for {obs_id}.')
    # because the type for the axes are 'LINEAR', which isn't an energy type,
    # so can't use the WcsParser from caom2utils.
    disp_axis = header.get('DISPAXIS')
    naxis = header.get('NAXIS')
    if disp_axis is not None and naxis is not None and disp_axis <= naxis:
        axis = Axis(ctype='WAVE', cunit='Angstrom')
        coord_axis_1d = CoordAxis1D(axis)
        ref_coord = RefCoord(
            pix=header.get(f'CRPIX{disp_axis}'),
            val=header.get(f'CRVAL{disp_axis}'),
        )
        fn = CoordFunction1D(
            naxis=header.get(f'NAXIS{disp_axis}'),
            delta=header.get(f'CD{disp_axis}_{disp_axis}'),
            ref_coord=ref_coord,
        )
        coord_axis_1d.function = fn
        energy = SpectralWCS(axis=coord_axis_1d, specsys='TOPOCENT')
        energy.bandpass_name = filter_name
        # DB 07-08-20
        # I think the best we can do is assume that a resolution element is 2
        # pixels wide. So resolving power is the absolute value of
        # approximately CRVAL3/(2 * CD3_3)
        energy.resolving_power = abs(
            header.get(f'CRVAL{disp_axis}') /
            (2 * header.get(f'CD{disp_axis}_{disp_axis}')))
        chunk.energy = energy
        chunk.energy_axis = disp_axis
    logging.debug('End _update_energy.')
Esempio n. 7
0
    def bad_delta():
        axis_1d = wcs.CoordAxis1D(wcs.Axis("UTC", "d"))
        temporal_wcs = chunk.TemporalWCS(axis_1d)

        # delta == 0.0 is bad
        ref_coord = wcs.RefCoord(float(1.0), float(2.0))
        temporal_wcs.axis.function = CoordFunction1D(int(100), 0.0, ref_coord)

        return temporal_wcs
Esempio n. 8
0
 def get_test_function_with_range(ctype, unit, px, sx, nx, ds):
     error = None
     start = RefCoord(float(0.9), float(1.1))
     end = RefCoord(float(10.9), float(11.1))
     range = CoordRange1D(start, end)
     axis_1d = CoordAxis1D(wcs.Axis(ctype, unit), error, range)
     ref_coord = RefCoord(px, sx)
     axis_1d.function = CoordFunction1D(nx, ds, ref_coord)
     custom_wcs = chunk.CustomWCS(axis_1d)
     return custom_wcs
Esempio n. 9
0
 def test_val2pix(self):
     # happy path
     wcs = CustomTestUtil.good_wcs()
     naxis = int(100)
     delta = -0.01
     ref_coord = RefCoord(0.0, 0.0)
     func = CoordFunction1D(naxis, delta, ref_coord)
     val = 0.1
     pix = wcs_util.CustomAxisUtil.val2pix(wcs, func, val)
     expected_pix = -10.0
     self.assertEqual(pix, expected_pix)
Esempio n. 10
0
 def test_function1d_to_interval_happy_path(self):
     # happy path
     wcs = CustomTestUtil.good_wcs()
     naxis = int(100)
     delta = -0.2
     ref_coord = RefCoord(0.0, 0.0)
     function_1d = CoordFunction1D(naxis, delta, ref_coord)
     actual_interval = wcs_util.CustomAxisUtil.function1d_to_interval(
         wcs, function_1d)
     expected_interval = Interval(-502.5, -2.5)
     self.assertEqual(expected_interval.lower, actual_interval.lower)
     self.assertEqual(expected_interval.upper, actual_interval.upper)
     self.assertEqual(None, actual_interval.samples)
     # function_1d.delta == 0.0 && function_1d.naxis > 1
     naxis = int(100)
     delta = 0.0
     ref_coord = RefCoord(0.0, 0.0)
     function_1d = CoordFunction1D(naxis, delta, ref_coord)
     with pytest.raises(ValueError) as ex:
         wcs_util.CustomAxisUtil.function1d_to_interval(wcs, function_1d)
     assert ('Invalid CoordFunction1D:' in str(ex.value))
Esempio n. 11
0
 def bad_function_wcs():
     ctype = "RM"
     unit = "rad/m^2"
     error = None
     range = None
     c1 = RefCoord(float(0.9), float(1.1))
     c2 = RefCoord(float(10.9), float(1.1))
     bounds = CoordBounds1D()
     bounds.samples.append(CoordRange1D(c1, c2))
     naxis = 1
     delta = 0.0
     ref_coord = RefCoord(float(0.9), float(1.1))
     func = CoordFunction1D(naxis, delta, ref_coord)
     axis_1d = CoordAxis1D(wcs.Axis(ctype, unit), error, range, bounds,
                           func)
     return chunk.CustomWCS(axis_1d)
Esempio n. 12
0
def _update_time(part, chunk, header, obs_id):
    logging.debug(f'Begin _update_time for {obs_id} part {part.name}.')

    # DB 02-07-20
    # time metadata comes from MJD_OBS and EXPTIME, it's not
    # an axis requiring cutout support
    exp_time = header.get('EXPTIME')
    mjd_obs = header.get('MJD_OBS')
    if exp_time is None or mjd_obs is None:
        chunk.time = None
    else:
        if chunk.time is None:
            coord_error = CoordError(syser=1e-07, rnder=1e-07)
            time_axis = CoordAxis1D(axis=Axis('TIME', 'd'), error=coord_error)
            chunk.time = TemporalWCS(axis=time_axis, timesys='UTC')
        ref_coord = RefCoord(pix=0.5, val=mjd_obs)
        chunk.time.axis.function = CoordFunction1D(
            naxis=1, delta=mc.convert_to_days(exp_time), ref_coord=ref_coord)
        chunk.time.exposure = float(exp_time)
        chunk.time.resolution = mc.convert_to_days(exp_time)
    logging.debug(f'End _update_time.')
Esempio n. 13
0
    def _update_time(self, chunk, obs_id):
        """Create TemporalWCS information using FITS header information.
        This information should always be available from the file."""
        self._logger.debug('Begin _update_time.')
        mc.check_param(chunk, Chunk)

        mjd_start = self._headers[0].get('MJD_STAR')
        mjd_end = self._headers[0].get('MJD_END')
        if mjd_start is None or mjd_end is None:
            mjd_start, mjd_end = ac.find_time_bounds(self._headers)
        if mjd_start is None or mjd_end is None:
            chunk.time = None
            self._logger.debug(
                f'Cannot calculate MJD_STAR {mjd_start} or ' f'MDJ_END'
                f' {mjd_end}'
            )
        elif mjd_start == 'NaN' or mjd_end == 'NaN':
            raise mc.CadcException(
                f'Invalid time values MJD_STAR {mjd_start} or MJD_END '
                f'{mjd_end} for {obs_id}, stopping ingestion.'
            )
        else:
            self._logger.debug(
                f'Calculating range with start {mjd_start} and end {mjd_end}.'
            )
            start = RefCoord(0.5, mjd_start)
            end = RefCoord(1.5, mjd_end)
            time_cf = CoordFunction1D(1, self._headers[0].get('TEFF'), start)
            time_axis = CoordAxis1D(Axis('TIME', 'd'), function=time_cf)
            time_axis.range = CoordRange1D(start, end)
            chunk.time = TemporalWCS(time_axis)
            chunk.time.exposure = self._headers[0].get('TEFF')
            chunk.time.resolution = 0.1
            chunk.time.timesys = 'UTC'
            chunk.time.trefpos = 'TOPOCENTER'
            chunk.time_axis = None
        self._logger.debug('Done _update_time.')
Esempio n. 14
0
 def get_test_function(ctype, unit, px, sx, nx, ds):
     axis_1d = CoordAxis1D(wcs.Axis(ctype, unit))
     ref_coord = RefCoord(px, sx)
     axis_1d.function = CoordFunction1D(nx, ds, ref_coord)
     custom_wcs = chunk.CustomWCS(axis_1d)
     return custom_wcs