Example #1
0
    def test_bounds(self):
        # Polarization bounds 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 bounds contains one valid range
        start = RefCoord(float(0.9), float(1.1))
        end = RefCoord(float(9.9), float(10.1))
        p_range = CoordRange1D(start, end)
        samples = caom_util.TypedList(CoordRange1D, p_range)
        axis_1d.bounds = CoordBounds1D(samples)
        polarization = PolarizationWCS(axis_1d)
        wcsvalidator._validate_polarization_wcs(polarization)

        # Polarization axis bounds contains more than one valid range
        start = RefCoord(float(0.9), float(1.1))
        end = RefCoord(float(9.9), float(10.1))
        p_range = CoordRange1D(start, end)
        start = RefCoord(float(-8.1), float(-7.9))
        end = RefCoord(float(-1.1), float(-0.9))
        n_range = CoordRange1D(start, end)
        samples = caom_util.TypedList(CoordRange1D, p_range, n_range)
        axis_1d.bounds = CoordBounds1D(samples)
        polarization = PolarizationWCS(axis_1d)
        wcsvalidator._validate_polarization_wcs(polarization)

        # Polarization axis bounds contains one invalid range
        start = RefCoord(float(0.9), float(1.1))
        end = RefCoord(float(10.9), float(11.1))
        p_range = CoordRange1D(start, end)
        samples = caom_util.TypedList(CoordRange1D, p_range)
        axis_1d.bounds = CoordBounds1D(samples)
        polarization = PolarizationWCS(axis_1d)
        with pytest.raises(InvalidWCSError) as ex:
            wcsvalidator._validate_polarization_wcs(polarization)
        assert ('Invalid Polarization WCS' in str(ex.value))
        assert ('11' in str(ex.value))

        # Polarization axis bounds contains more than one invalid range
        start = RefCoord(float(0.9), float(1.1))
        end = RefCoord(float(9.9), float(10.1))
        p_range = CoordRange1D(start, end)
        start = RefCoord(float(-9.1), float(-8.9))
        end = RefCoord(float(-1.1), float(-0.9))
        n_range = CoordRange1D(start, end)
        samples = caom_util.TypedList(CoordRange1D, p_range, n_range)
        axis_1d.bounds = CoordBounds1D(samples)
        polarization = PolarizationWCS(axis_1d)
        with pytest.raises(InvalidWCSError) as ex:
            wcsvalidator._validate_polarization_wcs(polarization)
        assert ('Invalid Polarization WCS' in str(ex.value))
        assert ('-9' in str(ex.value))
def build_chunk_energy_bounds(wave, axis):
    import numpy as np  # limit the  effect on container content

    # caom2IngestEspadons.py, l698
    x = np.arange(1, wave.size + 1, dtype='float32')
    wavegrade = np.gradient(wave)
    waveinflect = wave[np.where(abs(wavegrade) > 0.01)]
    xinflect = x[np.where(abs(wavegrade) > 0.01)]
    # add start and finish pixels onto waveinflect and xinflect and these are
    # our list of sub-bounds.
    allxinflect = np.append(x[0], xinflect)
    allxinflect = np.append(allxinflect, x[-1])
    allwaveinflect = np.append(wave[0], waveinflect)
    allwaveinflect = np.append(allwaveinflect, wave[-1])
    numwaveschunk = int(len(allxinflect) / 2.0)

    bounds = CoordBounds1D()
    for jj in range(numwaveschunk):
        indexlo = jj * 2 + 0
        indexhi = indexlo + 1
        x1 = float(allxinflect[indexlo])
        x2 = float(allxinflect[indexhi])
        w1 = float(allwaveinflect[indexlo])
        w2 = float(allwaveinflect[indexhi])
        coord_range = CoordRange1D(RefCoord(x1, w1), RefCoord(x2, w2))
        bounds.samples.append(coord_range)

    return bounds
Example #3
0
def _build_time(row):
    bounds = CoordBounds1D()
    start_date = ac.get_datetime(row[3].strip())
    end_date = ac.get_datetime(row[4].strip())
    start_date.format = 'mjd'
    end_date.format = 'mjd'
    exposure = float(ac.get_timedelta_in_s(row[5].strip()))
    start_ref_coord = RefCoord(0.5, start_date.value)
    end_ref_coord = RefCoord(1.5, end_date.value)
    bounds.samples.append(CoordRange1D(start_ref_coord, end_ref_coord))
    return bounds, exposure
Example #4
0
 def bad_bounds_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))
     axis_1d = CoordAxis1D(wcs.Axis(ctype, unit), error, range, bounds)
     return chunk.CustomWCS(axis_1d)
Example #5
0
    def _update_time_bounds(self, observation, storage_name):
        """Add chunk time bounds to the chunk from the first part, by
        referencing information from the second header."""

        lower_values = ''
        upper_values = ''
        with fits.open(storage_name.sources_names[0]) as fits_data:
            xtension = fits_data[1].header['XTENSION']
            extname = fits_data[1].header['EXTNAME']
            if 'BINTABLE' in xtension and 'PROVENANCE' in extname:
                for ii in fits_data[1].data[0]['STARTTIME']:
                    lower_values = f'{ii} {lower_values}'
                for ii in fits_data[1].data[0]['DURATION']:
                    upper_values = f'{ii} {upper_values} '
            else:
                raise mc.CadcException(
                    f'Opened a composite file that does not match the '
                    f'expected profile '
                    f'(XTENSION=BINTABLE/EXTNAME=PROVENANCE). '
                    f'{xtension} {extname}'
                )

        for plane in observation.planes:
            for artifact in observation.planes[plane].artifacts:
                parts = observation.planes[plane].artifacts[artifact].parts
                for p in parts:
                    if p == '0':
                        lower = lower_values.split()
                        upper = upper_values.split()
                        if len(lower) != len(upper):
                            raise mc.CadcException(
                                'Cannot make RefCoords with inconsistent '
                                'values.'
                            )
                        chunk = parts[p].chunks[0]
                        bounds = CoordBounds1D()
                        chunk.time.axis.bounds = bounds
                        for ii in range(len(lower)):
                            mjd_start, mjd_end = ac.convert_time(
                                mc.to_float(lower[ii]), mc.to_float(upper[ii])
                            )
                            lower_refcoord = RefCoord(0.5, mjd_start)
                            upper_refcoord = RefCoord(1.5, mjd_end)
                            r = CoordRange1D(lower_refcoord, upper_refcoord)
                            bounds.samples.append(r)
                        # if execution has gotten to this point, remove range
                        # if it exists, since only one of bounds or range
                        # should be provided, and bounds is more specific. PD,
                        # slack, 2018-07-16
                        if chunk.time.axis.range is not None:
                            chunk.time.axis.range = None
def _build_time(start, end, tos):
    bounds = CoordBounds1D()
    if start is not None and end is not None:
        start_date = ac.get_datetime(start)
        start_date.format = 'mjd'
        end_date = ac.get_datetime(end)
        end_date.format = 'mjd'
        start_ref_coord = RefCoord(0.5, start_date.value)
        end_ref_coord = RefCoord(1.5, end_date.value)
        bounds.samples.append(CoordRange1D(start_ref_coord, end_ref_coord))
    exposure = None
    if tos is not None:
        exposure = float(ac.get_timedelta_in_s(tos))
    return bounds, exposure
Example #7
0
def build_temporal_wcs_append_sample(temporal_wcs, lower, upper):
    """All the CAOM entities for building a TemporalWCS instance with
    a bounds definition, or appending a sample, in one function.
    """
    if temporal_wcs is None:
        samples = TypedList(CoordRange1D, )
        bounds = CoordBounds1D(samples=samples)
        temporal_wcs = TemporalWCS(axis=CoordAxis1D(axis=Axis('TIME', 'd'),
                                                    bounds=bounds),
                                   timesys='UTC')
    start_ref_coord = RefCoord(pix=0.5, val=lower)
    end_ref_coord = RefCoord(pix=1.5, val=upper)
    sample = CoordRange1D(start_ref_coord, end_ref_coord)
    temporal_wcs.axis.bounds.samples.append(sample)
    return temporal_wcs
Example #8
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)
    def bad_range_wcs():
        px = float(0.5)
        sx = float(54321.0)
        nx = 200
        ds = float(0.01)
        axis_1d = wcs.CoordAxis1D(wcs.Axis("RM", "rad/m**2"))

        # divide into 2 samples with a gap between
        c1 = RefCoord(px, sx)
        c2 = RefCoord(0.0, 0.0)
        c3 = RefCoord(px + nx * 0.66, sx + nx * ds * 0.66)
        c4 = RefCoord(px + nx, sx + nx * ds)
        axis_1d.bounds = CoordBounds1D()
        axis_1d.bounds.samples.append(CoordRange1D(c1, c3))
        axis_1d.bounds.samples.append(CoordRange1D(c4, c2))

        return chunk.CustomWCS(axis_1d)
 def get_test_function_with_bounds_3_samples(ctype, unit, px, sx, nx, ds):
     error = None
     range = None
     start = RefCoord(float(0.8), float(1.1))
     end = RefCoord(float(10.8), float(11.1))
     b_range_1 = CoordRange1D(start, end)
     start = RefCoord(float(0.9), float(1.2))
     end = RefCoord(float(10.9), float(11.2))
     b_range_2 = CoordRange1D(start, end)
     start = RefCoord(float(-0.9), float(-1.2))
     end = RefCoord(float(0.6), float(0.2))
     b_range_3 = CoordRange1D(start, end)
     samples = caom_util.TypedList(CoordRange1D, b_range_1, b_range_2,
                                   b_range_3)
     bounds = CoordBounds1D(samples)
     axis_1d = wcs.CoordAxis1D(wcs.Axis(ctype, unit), error, range, bounds)
     ref_coord = wcs.RefCoord(px, sx)
     axis_1d.function = wcs.CoordFunction1D(nx, ds, ref_coord)
     custom_wcs = chunk.CustomWCS(axis_1d)
     return custom_wcs
Example #11
0
def _update_ngvs_time(chunk, provenance, obs_id):
    logging.debug(f'Begin _update_ngvs_time for {obs_id}')
    if (chunk is not None and provenance is not None and
            len(provenance.inputs) > 0):
        # bounds = ctor
        config = mc.Config()
        config.get_executors()
        subject = mc.define_subject(config)
        client = CAOM2RepoClient(
            subject, config.logging_level, 'ivo://cadc.nrc.ca/ams')
        metrics = mc.Metrics(config)
        bounds = CoordBounds1D()
        min_date = 0
        max_date = sys.float_info.max
        exposure = 0
        for entry in provenance.inputs:
            ip_obs_id, ip_product_id = mc.CaomName.decompose_provenance_input(
                entry.uri)
            logging.info(f'Retrieving provenance metadata for {ip_obs_id}.')
            ip_obs = mc.repo_get(client, 'CFHT', ip_obs_id, metrics)
            if ip_obs is not None:
                ip_plane = ip_obs.planes.get(ip_product_id)
                if (ip_plane is not None and ip_plane.time is not None and
                        ip_plane.time.bounds is not None):
                    bounds.samples.append(CoordRange1D(
                        RefCoord(pix=0.5, val=ip_plane.time.bounds.lower),
                        RefCoord(pix=1.5, val=ip_plane.time.bounds.upper)))
                    min_date = min(ip_plane.time.bounds.lower, min_date)
                    max_date = max(ip_plane.time.bounds.upper, max_date)
                    exposure += ip_plane.time.exposure
        axis = Axis(ctype='TIME', cunit='d')
        time_axis = CoordAxis1D(axis=axis,
                                error=None,
                                range=None,
                                bounds=bounds,
                                function=None)
        temporal_wcs = TemporalWCS(axis=time_axis, timesys=None, trefpos=None,
                                   mjdref=None, exposure=mc.to_float(exposure),
                                   resolution=None)
        chunk.time = temporal_wcs
    logging.debug(f'End _update_ngvs_time.')
Example #12
0
def _update_from_comment(observation, phangs_name, headers):
    # From ER: 04-03-21
    # COMMENT Produced with PHANGS-ALMA pipeline version 4.0 Build 935
    # - Provenance.version
    # COMMENT Galaxy properties from PHANGS sample table version 1.6
    # COMMENT Calibration Level 4 (ANALYSIS_PRODUCT)
    # - Calibration level (either 3 or 4)
    # COMMENT PHANGS-ALMA Public Release 1
    # - Provenance.project = PHANGS-ALMA
    # COMMENT Generated by the Physics at High Angular resolution
    # COMMENT in nearby GalaxieS (PHANGS) collaboration
    # - Provenance.organization = PHANGS
    # COMMENT Canonical Reference: Leroy et al. (2021), ApJ, Submitted
    # - Update to reference when accepted
    # COMMENT Release generated at 2021-03-04T07:28:10.245340
    # - Provenance.lastExecuted
    # COMMENT Data from ALMA Proposal ID: 2017.1.00886.L
    # - Proposal.proposalID
    # COMMENT ALMA Proposal PI: Schinnerer, Eva
    # - Proposal.pi_name
    # COMMENT Observed in MJD interval [58077.386275,58081.464121]
    # COMMENT Observed in MJD interval [58290.770032,58365.629222]
    # COMMENT Observed in MJD interval [58037.515807,58047.541173]
    # COMMENT Observed in MJD interval [58353.589805,58381.654757]
    # COMMENT Observed in MJD interval [58064.3677,58072.458597]
    # COMMENT Observed in MJD interval [58114.347649,58139.301879]
    chunk = None
    for plane in observation.planes.values():
        if plane.product_id != phangs_name.product_id:
            continue
        if plane.provenance is None:
            plane.provenance = Provenance(name='PHANGS-ALMA pipeline')

        for artifact in plane.artifacts.values():
            if artifact.uri != phangs_name.file_uri:
                continue
            for part in artifact.parts.values():
                chunk = part.chunks[0]
                break

        for entry in headers[0].get('COMMENT'):
            if 'pipeline version ' in entry:
                plane.provenance.version = entry.split(' version ')[1]
            elif 'Calibration Level' in entry:
                level = entry.split()[2]
                if level == '4':
                    plane.calibration_level = CalibrationLevel.ANALYSIS_PRODUCT
            elif 'PHANGS-ALMA Public Release' in entry:
                plane.provenance.project = 'PHANGS-ALMA'
            elif 'in nearby GalaxieS (PHANGS) collaboration' in entry:
                plane.provenance.organization = 'PHANGS'
            elif 'Release generated at ' in entry:
                plane.provenance.last_executed = mc.make_time_tz(
                    entry.split(' at ')[1])
            elif 'Data from ALMA Proposal ID:' in entry:
                observation.proposal = Proposal(entry.split(':')[1].strip())
            elif 'Canonical Reference: ' in entry:
                plane.provenance.producer = entry.split(': ')[1]
            elif 'ALMA Proposal PI:' in entry:
                observation.proposal.pi_name = entry.split(': ')[1]
            elif 'Observed in MJD interval ' in entry:
                if chunk is not None:
                    bits = entry.split()[4].split(',')
                    start_ref_coord = RefCoord(
                        0.5, mc.to_float(bits[0].replace('[', '')))
                    end_ref_coord = RefCoord(
                        1.5, mc.to_float(bits[1].replace(']', '')))
                    sample = CoordRange1D(start_ref_coord, end_ref_coord)
                    if chunk.time is None:
                        coord_bounds = CoordBounds1D()
                        axis = CoordAxis1D(axis=Axis('TIME', 'd'))
                        chunk.time = TemporalWCS(axis, timesys='UTC')
                        chunk.time.axis.bounds = coord_bounds
                    chunk.time.axis.bounds.samples.append(sample)