def _interp_time_orientation(self, time: Time) -> xr.DataArray: """Interpolate the orientation in time.""" if "time" not in self.orientation.dims: # don't interpolate static return self.orientation if time.max() <= self.time.min(): # only use edge timestamp return self.orientation.isel(time=0).data if time.min() >= self.time.max(): # only use edge timestamp return self.orientation.isel(time=-1).data # full interpolation with overlapping times return ut.xr_interp_orientation_in_time(self.orientation, time)
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
def _interp_time_coordinates(self, time: Time) -> xr.DataArray: """Interpolate the coordinates in time.""" if isinstance(self.coordinates, TimeSeries): time_interp = Time(time, self.reference_time) coordinates = self._coords_from_discrete_time_series( self.coordinates.interp_time(time_interp) ) if self.has_reference_time: coordinates.weldx.time_ref = self.reference_time return coordinates if "time" not in self.coordinates.dims: # don't interpolate static return self.coordinates if time.max() <= self.time.min(): # only use edge timestamp return self.coordinates.isel(time=0).data if time.min() >= self.time.max(): # only use edge timestamp return self.coordinates.isel(time=-1).data # full interpolation with overlapping times return ut.xr_interp_coordinates_in_time(self.coordinates, time)