示例#1
0
def xr_interp_orientation_in_time(da: xr.DataArray,
                                  time: types_time_like) -> xr.DataArray:
    """Interpolate an xarray DataArray that represents orientation data in time.

    Parameters
    ----------
    da :
        xarray DataArray containing the orientation as matrix
    time :
        Time data

    Returns
    -------
    xarray.DataArray
        Interpolated data

    """
    if "time" not in da.dims:
        return da
    if len(da.time) == 1:  # remove "time dimension" for static case
        return da.isel({"time": 0})

    time = Time(time).as_pandas_index()
    time_da = Time(da).as_pandas_index()
    time_ref = da.weldx.time_ref

    if not len(time_da) > 1:
        raise ValueError("Invalid time format for interpolation.")

    # extract intersecting times and add time range boundaries of the data set
    times_ds_limits = pd.Index([time_da.min(), time_da.max()])
    times_union = time.union(times_ds_limits)
    times_intersect = times_union[(times_union >= times_ds_limits[0])
                                  & (times_union <= times_ds_limits[1])]

    # interpolate rotations in the intersecting time range
    rotations_key = Rot.from_matrix(da.transpose(..., "time", "c", "v").data)
    times_key = time_da.view(np.int64)
    rotations_interp = Slerp(times_key,
                             rotations_key)(times_intersect.view(np.int64))
    da = xr_3d_matrix(rotations_interp.as_matrix(), times_intersect)

    # use interp_like to select original time values and correctly fill time dimension
    da = xr_interp_like(da, {"time": time}, fillna=True)

    # resync and reset to correct format
    if time_ref:
        da.weldx.time_ref = time_ref
    da = da.weldx.time_ref_restore().transpose(..., "time", "c", "v")

    if len(da.time) == 1:  # remove "time dimension" for static case
        return da.isel({"time": 0})

    return da
示例#2
0
文件: util.py 项目: BAMWelDX/weldx
def xr_interp_orientation_in_time(
    dsx: xr.DataArray, times: Union[pd.DatetimeIndex, pd.TimedeltaIndex]
) -> xr.DataArray:
    """Interpolate an xarray DataArray that represents orientation data in time.

    Parameters
    ----------
    dsx :
        xarray DataArray containing the orientation as matrix
    times :
        Time data

    Returns
    -------
    xarray.DataArray
        Interpolated data

    """
    if "time" not in dsx.coords:
        return dsx

    times = to_pandas_time_index(times)
    times_ds = to_pandas_time_index(dsx)
    time_ref = dsx.weldx.time_ref

    if len(times_ds) > 1:
        # extract intersecting times and add time range boundaries of the data set
        times_ds_limits = pd.Index([times_ds.min(), times_ds.max()])
        times_union = times.union(times_ds_limits)
        times_intersect = times_union[
            (times_union >= times_ds_limits[0]) & (times_union <= times_ds_limits[1])
        ]

        # interpolate rotations in the intersecting time range
        rotations_key = Rot.from_matrix(dsx.transpose(..., "c", "v").data)
        times_key = times_ds.astype(np.int64)
        rotations_interp = Slerp(times_key, rotations_key)(
            times_intersect.astype(np.int64)
        )
        dsx_out = xr_3d_matrix(rotations_interp.as_matrix(), times_intersect)
    else:
        # TODO: this case is not really well defined, maybe avoid?
        dsx_out = dsx

    # use interp_like to select original time values and correctly fill time dimension
    dsx_out = xr_interp_like(dsx_out, {"time": times}, fillna=True)

    # resync and reset to correct format
    if time_ref:
        dsx_out.weldx.time_ref = time_ref
    dsx_out = dsx_out.weldx.time_ref_restore()

    return dsx_out.transpose(..., "c", "v")