def test_validate_observation():
    obs = SimpleObservation('test_collection', 'test_obs_id',
                            Algorithm('test_name'))
    validate(obs)
    obs = DerivedObservation('test_collection', 'test_obs_id',
                             Algorithm('test_name'),
                             proposal=Proposal('test_proposal'),
                             telescope=Telescope('test_telescope'),
                             instrument=Instrument('test_instrument'),
                             target=Target('test_targets'))
    obs.algorithm.keywords = 'foo'
    obs.proposal.keywords = set('foo=42')
    obs.telescope.keywords = set('foo:42')
    obs.instrument.keywords.add("tick'marks")
    obs.target.keywords = set('has multiple spaces')
    test_plane = Plane('test_plane')
    test_plane.provenance = Provenance('test_provenance')
    test_plane.provenance.keywords.add('pipe|denied')
    obs.planes['test_plane'] = test_plane
    with pytest.raises(AssertionError):
        validate(obs)
Example #2
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)
Example #3
0
def stuff(args):
    obs = None
    index = 0
    for f_name in args.local:
        product_id = args.lineage[index].split('/')[0]
        t_header = Table.read(f_name, format='hdf5', path='header')
        # logging.error(t_header.colnames)
        # ['VERSION_MAJOR', 'VERSION_MINOR', 'TIME_IN_SEC',
        # 'TIME_IN_MICROSEC', 'RUN_ID', 'ORIGIN', 'OBSMODE', 'FIELD', 'RA',
        # 'DEC', 'EXPTIME', 'NUM_IMAGER']
        # logging.error(t_header)

        # t_header['RUN_ID'].data[0].decode() - return this string
        # 20190805T024026
        # logging.error(t_header['RUN_ID'].data[0].decode())
        release_date = datetime.strptime(
            t_header['RUN_ID'].data[0].decode(), '%Y%m%dT%H%M%S')

        t_image = Table.read(f_name, format='hdf5', path='image')
        # logging.error(t_image.colnames)
        # ['col0', 'col1', 'col2']
        # logging.error(t_image)
        # logging.error(t_image['col0'].data[0])
        # logging.error(t_image['col0'].data[143999])

        t_catalog = Table.read(f_name, format='hdf5', path='catalog')
        # logging.error(t_catalog.colnames)
        # ['CAT_ID', 'GAIA_ID', '2MASS_ID', 'RA', 'DEC', 'TAOS_MAG',
        # 'GAIA_MAG', '2MASS_JMAG']
        # logging.error(t_catalog)

        t_imager = Table.read(f_name, format='hdf5', path='imager')
        # logging.error(t_imager.colnames)
        # ['TEL_ID', 'CAM_ID', 'IMGR_ID', 'XLOC', 'YLOC']
        # logging.error(t_imager)

        t_moment = Table.read(f_name, format='hdf5', path='moment')
        # logging.error(t_moment.colnames)
        # ['col0', 'col1', 'col2']
        # logging.error(t_moment)

        t_window = Table.read(f_name, format='hdf5', path='window')
        # logging.error(t_window.colnames)
        # ['X0', 'X1', 'Y0', 'Y1', 'XC', 'YC']
        # logging.error(t_window)

        t_wcs= Table.read(f_name, format='hdf5', path='/wcs/cdmatrix')
        # ['CRVAL1','CRVAL2','CRPIX1','CRPIX2','CD1_1','CD1_2','CD2_1','CD2_2']
        # logging.error(t_wcs)

        taos = Telescope(name='TAOS',
                         geo_location_x=-2354953.99637757,
                         geo_location_y=-4940160.3636381,
                         geo_location_z=3270123.70695983)

        target = Target(name=str(t_header['FIELD'].data[0]),
                        target_type=TargetType.FIELD,
                        standard=None,
                        redshift=None,
                        keywords=None,
                        moving=None)

        proposal = Proposal(id=COLLECTION,
                            pi_name=None,
                            project=COLLECTION,
                            title=None)

        obs = SimpleObservation(collection=COLLECTION,
                                observation_id=args.observation[1],
                                sequence_number=None,
                                intent=ObservationIntentType.SCIENCE,
                                type='FIELD',
                                proposal=proposal,
                                telescope=taos,
                                instrument=None,
                                target=target,
                                meta_release=release_date)

        provenance = Provenance(name=COLLECTION,
                                version='{}.{}'.format(
                                    t_header['VERSION_MAJOR'].data[0],
                                    t_header['VERSION_MINOR'].data[0]),
                                project=COLLECTION,
                                producer=COLLECTION,
                                run_id=t_header['RUN_ID'].data[0].decode(),
                                reference='https://taos2.asiaa.sinica.edu.tw/',
                                last_executed=release_date)

        plane = Plane(product_id=product_id,
                      data_release=release_date,
                      meta_release=release_date,
                      provenance=provenance,
                      data_product_type=DataProductType.IMAGE,
                      calibration_level=CalibrationLevel.RAW_STANDARD)

        artifact = mc.get_artifact_metadata(
            f_name, ProductType.SCIENCE, ReleaseType.DATA,
            mc.build_uri(COLLECTION, os.path.basename(f_name)))

        # parts are always named '0'
        part = Part('0')

        # do each of the three telescopes
        for telescope in [0, 1, 2]:
            position = build_position(t_wcs,
                                      t_window,
                                      telescope)

            time = build_time(t_header['TIME_IN_SEC'].data[0],
                              t_header['TIME_IN_MICROSEC'].data[0])

            energy = build_energy()

            chunk = Chunk(naxis=4,
                          position_axis_1=1,
                          position_axis_2=2,
                          energy_axis=3,
                          time_axis=4,
                          position=position,
                          energy=energy,
                          time=time)

            part.chunks.append(chunk)

        artifact.parts.add(part)
        plane.artifacts.add(artifact)
        obs.planes.add(plane)

        index += 1

    return obs
Example #4
0
def _build_obs(override, db_content, fqn, index, almaca_name, md_name):

    obs_date = db_content['Observation date'][index]
    if obs_date is None:
        raise mc.CadcException('No observation date for {}'.format(fqn))
    else:
        obs_date = time.Time(obs_date).to_datetime()

    # of_site('alma')
    # 2225015.30883296, -5440016.41799762, -2481631.27428014
    #
    size = db_content['Array'][index]
    telescope = Telescope(name="ALMA-{}".format(size),
                          geo_location_x=2225142.18,
                          geo_location_y=-5440307.37,
                          geo_location_z=-2481029.852)

    instrument = Instrument(name=_get_band_name(override))

    # HK - 14-08-19
    # target: this should be the science target / science fieldname and
    # not the calibrator fieldname, as it is presently (i.e., should be
    # J1851+0035, not J1924-2914).  Or, we may need to continue to leave
    # that field blank at this level.  A single calibrated measurement set
    # may contain multiple science target names, which would not be
    # properly captured at this level.  [For the raw data, the target
    # field is left blank]
    target = Target(name=override.get('field'),
                    standard=False,
                    moving=False,
                    target_type=TargetType.OBJECT)

    # HK - 07-02-20
    # Since we've changed what the base level observation is and can now list
    # a target name in the 'Derived Observation' base plane, I believe that
    # means we can also include that target's position under targetPosition.
    # You've already pulled this info out for the subsequent levels of the
    # hierarchy under 'position', so it's presumably fairly straightforward to
    # include the same info here.
    result_ra, result_dec = _get_ra_dec(md_name)
    point = Point(result_ra, result_dec)
    target_position = TargetPosition(
        coordinates=point,
        coordsys='ICRS',  # from listobs output
        equinox=2000.0)  # a guess by google

    # db_content as votable:
    # >>> t.colnames
    # ['Project_code', 'Source_name', 'RA', 'Dec', 'Galactic_longitude',
    # 'Galactic_latitude', 'Band', 'Spatial_resolution',
    # 'Frequency_resolution', 'Array', 'Mosaic', 'Integration',
    # 'Release_date', 'Frequency_support', 'Velocity_resolution',
    # 'Pol_products', 'Observation_date', 'PI_name', 'SB_name',
    # 'Proposal_authors', 'Line_sensitivity__10_km_s_',
    # 'Continuum_sensitivity', 'PWV', 'Group_ous_id', 'Member_ous_id',
    # 'Asdm_uid', 'Project_title', 'Project_type', 'Scan_intent',
    # 'Field_of_view', 'Largest_angular_scale', 'QA2_Status', 'COUNT',
    # 'Science_keyword', 'Scientific_category', 'ASA_PROJECT_CODE']
    #
    # db_content.colnames as html:
    #
    # ['Project code', 'Source name', 'RA', 'Dec', 'Galactic longitude',
    # 'Galactic latitude', 'Band', 'Spatial resolution',
    # 'Frequency resolution', 'Array', 'Mosaic', 'Integration',
    # 'Release date', 'Frequency support', 'Velocity resolution',
    # 'Pol products', 'Observation date', 'PI name', 'SB name',
    # 'Proposal authors', 'Line sensitivity (10 km/s)',
    # 'Continuum sensitivity', 'PWV', 'Group ous id', 'Member ous id',
    # 'Asdm uid', 'Project title', 'Project type', 'Scan intent',
    # 'Field of view', 'Largest angular scale', 'QA2 Status', 'COUNT',
    # 'Science keyword', 'Scientific category', 'ASA_PROJECT_CODE']

    # HK - 14-08-19
    # can we include the project code, and not just the observation UID
    # somewhere in here?  For the raw data, it looks like the project
    # code was included as 'proposal: ID', whereas for the calibrated
    # measurement set, proposal: ID is now set to the UID and the project
    # code (2016.1.00010.S) is not captured anywhere.  Could the 'project'
    # field, currently set as 'null' be used for this?
    proposal = Proposal(id=db_content['Project code'][index],
                        project=override.get('project'),
                        pi_name=db_content['PI name'][index],
                        title=db_content['Project title'][index])

    keywords = db_content['Science keyword'][index]
    if keywords is not None:
        proposal.keywords = set(keywords.split())

    environment = Environment()
    environment.tau = db_content['PWV'][index] / 0.935 + 0.35
    environment.wavelength_tau = 350 * units.um.to(units.meter)

    intent = (ObservationIntentType.SCIENCE
              if almaca_name.intent is ProductType.SCIENCE else
              ObservationIntentType.CALIBRATION)

    algorithm = Algorithm(name='single band split')
    #
    # PD, SG 15-08-19
    # make it a composite, algorithm name something like
    # 'target splitting'
    #
    observation = DerivedObservation(collection=ARCHIVE,
                                     observation_id=almaca_name.obs_id,
                                     sequence_number=None,
                                     intent=intent,
                                     type="OBJECT",
                                     proposal=proposal,
                                     telescope=telescope,
                                     instrument=instrument,
                                     target=target,
                                     meta_release=obs_date,
                                     algorithm=algorithm,
                                     environment=environment,
                                     target_position=target_position)
    observation.members.add(
        ObservationURI(
            mc.CaomName.make_obs_uri_from_obs_id('ALMA', 'A001_X88b_X23')))
    return observation