示例#1
0
    def test_update_crs(self):
        # Test copying allows the CRS to be updated on the copy w/out changing the source CRS.
        desired = Spherical()
        gvar = GeometryVariable(value=[Point(1, 2)], name='geom', dimensions='geom')
        field = Field(crs=desired, geom=gvar)
        cfield = field.copy()
        self.assertEqual(cfield.crs, desired)
        new_crs = CoordinateReferenceSystem(name='i_am_new', epsg=4326)
        cfield.update_crs(new_crs)
        self.assertEqual(field.crs, desired)

        # Test geometry crs update is called.
        mfield = Mock(Field)
        mfield.is_empty = False
        mfield.dimension_map = Mock(DimensionMap)
        mfield.grid = Mock(Grid)
        mfield.geom = Mock(GeometryVariable)
        mcrs = Mock(Spherical)
        Field.update_crs(mfield, mcrs)
        mfield.grid.update_crs.assert_called_once_with(mcrs, from_crs=mfield.crs)
        mfield.geom.update_crs.assert_called_once_with(mcrs, from_crs=mfield.crs)
        from_crs = Mock(WGS84)
        mfield.grid.update_crs.reset_mock()
        mfield.geom.update_crs.reset_mock()
        Field.update_crs(mfield, mcrs, from_crs=from_crs)
        mfield.grid.update_crs.assert_called_once_with(mcrs, from_crs=from_crs)
        mfield.geom.update_crs.assert_called_once_with(mcrs, from_crs=from_crs)
示例#2
0
def _update_aggregation_wrapping_crs_(obj, alias, sfield, subset_sdim,
                                      subset_ugid):
    raise_if_empty(sfield)

    ocgis_lh('entering _update_aggregation_wrapping_crs_',
             obj._subset_log,
             alias=alias,
             ugid=subset_ugid,
             level=logging.DEBUG)

    # Aggregate if requested.
    if obj.ops.aggregate:
        ocgis_lh('aggregate requested in _update_aggregation_wrapping_crs_',
                 obj._subset_log,
                 alias=alias,
                 ugid=subset_ugid,
                 level=logging.DEBUG)

        # There may be no geometries if we are working with a gridded dataset. Load the geometries if this is the case.
        sfield.set_abstraction_geom()

        ocgis_lh(
            'after sfield.set_abstraction_geom in _update_aggregation_wrapping_crs_',
            obj._subset_log,
            alias=alias,
            ugid=subset_ugid,
            level=logging.DEBUG)

        # Union the geometries and spatially average the data variables.
        # with vm.scoped(vm.get_live_ranks_from_object(sfield)):
        sfield = sfield.geom.get_unioned(spatial_average=sfield.data_variables)
        ocgis_lh(
            'after sfield.geom.get_unioned in _update_aggregation_wrapping_crs_',
            obj._subset_log,
            alias=alias,
            ugid=subset_ugid,
            level=logging.DEBUG)

        # None is returned for the non-root process. Check we are in parallel and create an empty field.
        if sfield is None:
            if vm.size == 1:
                raise ValueError(
                    'None should not be returned from get_unioned if running on a single processor.'
                )
            else:
                sfield = Field(is_empty=True)
        else:
            sfield = sfield.parent

        vm.create_subcomm_by_emptyable(SubcommName.SPATIAL_AVERAGE,
                                       sfield,
                                       is_current=True,
                                       clobber=True)

        if not vm.is_null and subset_sdim is not None and subset_sdim.geom is not None:
            # Add the unique geometry identifier variable. This should match the selection geometry's identifier.
            new_gid_variable_kwargs = dict(
                name=HeaderName.ID_GEOMETRY,
                value=subset_sdim.geom.ugid.get_value(),
                dimensions=sfield.geom.dimensions)
            dm = get_data_model(obj.ops)
            new_gid_variable = create_typed_variable_from_data_model(
                'int', data_model=dm, **new_gid_variable_kwargs)
            sfield.geom.set_ugid(new_gid_variable)

    if vm.is_null:
        ocgis_lh(msg='null communicator following spatial average. returning.',
                 logger=obj._subset_log,
                 level=logging.DEBUG)
        return sfield

    raise_if_empty(sfield)
    ocgis_lh(msg='before wrapped_state in _update_aggregation_wrapping_crs_',
             logger=obj._subset_log,
             level=logging.DEBUG)
    try:
        wrapped_state = sfield.wrapped_state
    except WrappedStateEvalTargetMissing:
        # If there is no target for wrapping evaluation, then consider this unknown.
        wrapped_state = WrappedState.UNKNOWN
    ocgis_lh(msg='after wrapped_state in _update_aggregation_wrapping_crs_',
             logger=obj._subset_log,
             level=logging.DEBUG)

    # Wrap the returned data.
    if not env.OPTIMIZE_FOR_CALC and not sfield.is_empty:
        if wrapped_state == WrappedState.UNWRAPPED:
            ocgis_lh('wrap target is empty: {}'.format(sfield.is_empty),
                     obj._subset_log,
                     level=logging.DEBUG)

            # There may be no geometries if we are working with a gridded dataset. Load the geometries if this
            # is the case.
            sfield.set_abstraction_geom()

            if obj.ops.output_format in constants.VECTOR_OUTPUT_FORMATS and obj.ops.vector_wrap:
                ocgis_lh('wrapping output geometries',
                         obj._subset_log,
                         alias=alias,
                         ugid=subset_ugid,
                         level=logging.DEBUG)

                # Deepcopy geometries before wrapping as wrapping will be performed inplace. The original field may
                # need to be reused for additional subsets.
                geom = sfield.geom
                copied_geom = geom.get_value().copy()
                geom.set_value(copied_geom)
                # Some grids do not play nicely with wrapping. Bounds may be less than zero for an unwrapped grid.
                # Force wrapping if it is requested. Normally, when force is false there is a pass-through that will
                # leave the data untouched.
                geom.wrap(force=True)
                ocgis_lh('finished wrapping output geometries',
                         obj._subset_log,
                         alias=alias,
                         ugid=subset_ugid,
                         level=logging.DEBUG)

    # Transform back to rotated pole if necessary.
    original_rotated_pole_crs = obj._backtransform.get(
        constants.BackTransform.ROTATED_POLE)
    if original_rotated_pole_crs is not None:
        if not isinstance(obj.ops.output_crs, (Spherical, WGS84)):
            sfield.update_crs(original_rotated_pole_crs)

    # Update the coordinate system of the data output.
    if obj.ops.output_crs is not None:

        # If the geometry is not none, it may need to be projected to match the output coordinate system.
        if subset_sdim is not None and subset_sdim.crs != obj.ops.output_crs:
            subset_sdim.update_crs(obj.ops.output_crs)

        # Update the subsetted field's coordinate system.
        sfield = sfield.copy()
        sfield.update_crs(obj.ops.output_crs)

    # Wrap or unwrap the data if the coordinate system permits.
    _update_wrapping_(obj, sfield)

    ocgis_lh('leaving _update_aggregation_wrapping_crs_',
             obj._subset_log,
             level=logging.DEBUG)

    return sfield
示例#3
0
文件: engine.py 项目: NCPP/ocgis
def _update_aggregation_wrapping_crs_(obj, alias, sfield, subset_sdim, subset_ugid):
    raise_if_empty(sfield)

    ocgis_lh('entering _update_aggregation_wrapping_crs_', obj._subset_log, alias=alias,
             ugid=subset_ugid, level=logging.DEBUG)

    # Aggregate if requested.
    if obj.ops.aggregate:
        ocgis_lh('aggregate requested in _update_aggregation_wrapping_crs_', obj._subset_log, alias=alias,
                 ugid=subset_ugid, level=logging.DEBUG)

        # There may be no geometries if we are working with a gridded dataset. Load the geometries if this is the case.
        sfield.set_abstraction_geom()

        ocgis_lh('after sfield.set_abstraction_geom in _update_aggregation_wrapping_crs_', obj._subset_log, alias=alias,
                 ugid=subset_ugid, level=logging.DEBUG)

        # Union the geometries and spatially average the data variables.
        # with vm.scoped(vm.get_live_ranks_from_object(sfield)):
        sfield = sfield.geom.get_unioned(spatial_average=sfield.data_variables)
        ocgis_lh('after sfield.geom.get_unioned in _update_aggregation_wrapping_crs_', obj._subset_log, alias=alias,
                 ugid=subset_ugid, level=logging.DEBUG)

        # None is returned for the non-root process. Check we are in parallel and create an empty field.
        if sfield is None:
            if vm.size == 1:
                raise ValueError('None should not be returned from get_unioned if running on a single processor.')
            else:
                sfield = Field(is_empty=True)
        else:
            sfield = sfield.parent

        vm.create_subcomm_by_emptyable(SubcommName.SPATIAL_AVERAGE, sfield, is_current=True, clobber=True)

        if not vm.is_null and subset_sdim is not None and subset_sdim.geom is not None:
            # Add the unique geometry identifier variable. This should match the selection geometry's identifier.
            new_gid_variable_kwargs = dict(name=HeaderName.ID_GEOMETRY, value=subset_sdim.geom.ugid.get_value(),
                                           dimensions=sfield.geom.dimensions)
            dm = get_data_model(obj.ops)
            new_gid_variable = create_typed_variable_from_data_model('int', data_model=dm, **new_gid_variable_kwargs)
            sfield.geom.set_ugid(new_gid_variable)

    if vm.is_null:
        ocgis_lh(msg='null communicator following spatial average. returning.', logger=obj._subset_log,
                 level=logging.DEBUG)
        return sfield

    raise_if_empty(sfield)
    ocgis_lh(msg='before wrapped_state in _update_aggregation_wrapping_crs_', logger=obj._subset_log,
             level=logging.DEBUG)
    try:
        wrapped_state = sfield.wrapped_state
    except WrappedStateEvalTargetMissing:
        # If there is no target for wrapping evaluation, then consider this unknown.
        wrapped_state = WrappedState.UNKNOWN
    ocgis_lh(msg='after wrapped_state in _update_aggregation_wrapping_crs_', logger=obj._subset_log,
             level=logging.DEBUG)

    # Wrap the returned data.
    if not env.OPTIMIZE_FOR_CALC and not sfield.is_empty:
        if wrapped_state == WrappedState.UNWRAPPED:
            ocgis_lh('wrap target is empty: {}'.format(sfield.is_empty), obj._subset_log, level=logging.DEBUG)

            # There may be no geometries if we are working with a gridded dataset. Load the geometries if this
            # is the case.
            sfield.set_abstraction_geom()

            if obj.ops.output_format in constants.VECTOR_OUTPUT_FORMATS and obj.ops.vector_wrap:
                ocgis_lh('wrapping output geometries', obj._subset_log, alias=alias, ugid=subset_ugid,
                         level=logging.DEBUG)

                # Deepcopy geometries before wrapping as wrapping will be performed inplace. The original field may
                # need to be reused for additional subsets.
                geom = sfield.geom
                copied_geom = geom.get_value().copy()
                geom.set_value(copied_geom)
                # Some grids do not play nicely with wrapping. Bounds may be less than zero for an unwrapped grid.
                # Force wrapping if it is requested. Normally, when force is false there is a pass-through that will
                # leave the data untouched.
                geom.wrap(force=True)
                ocgis_lh('finished wrapping output geometries', obj._subset_log, alias=alias, ugid=subset_ugid,
                         level=logging.DEBUG)

    # Transform back to rotated pole if necessary.
    original_rotated_pole_crs = obj._backtransform.get(constants.BackTransform.ROTATED_POLE)
    if original_rotated_pole_crs is not None:
        if not isinstance(obj.ops.output_crs, (Spherical, WGS84)):
            sfield.update_crs(original_rotated_pole_crs)

    # Update the coordinate system of the data output.
    if obj.ops.output_crs is not None:

        # If the geometry is not none, it may need to be projected to match the output coordinate system.
        if subset_sdim is not None and subset_sdim.crs != obj.ops.output_crs:
            subset_sdim.update_crs(obj.ops.output_crs)

        # Update the subsetted field's coordinate system.
        sfield = sfield.copy()
        sfield.update_crs(obj.ops.output_crs)

    # Wrap or unwrap the data if the coordinate system permits.
    _update_wrapping_(obj, sfield)

    ocgis_lh('leaving _update_aggregation_wrapping_crs_', obj._subset_log, level=logging.DEBUG)

    return sfield