def vtk_export_unstructured(filename, pos, fields): # pragma: no cover """Export a field to vtk structured rectilinear grid file. Parameters ---------- filename : :class:`str` Filename of the file to be saved, including the path. Note that an ending (.vtu) will be added to the name. pos : :class:`list` the position tuple, containing main direction and transversal directions fields : :class:`dict` or :class:`numpy.ndarray` Unstructured fields to be saved. Either a single numpy array as returned by SRF, or a dictionary of fields with theirs names as keys. """ if not isinstance(fields, dict): fields = {"field": fields} x, y, z = pos2xyz(pos) if y is None: y = np.zeros_like(x) if z is None: z = np.zeros_like(x) for field in fields: fields[field] = fields[field].reshape(-1) if (len(fields[field]) != len(x) or len(fields[field]) != len(y) or len(fields[field]) != len(z)): raise ValueError("gstools.vtk_export_unstructured: " + "field shape doesn't match the given mesh") pointsToVTK(filename, x, y, z, data=fields)
def _get_iso_rad(self, pos): x, y, z = pos2xyz(pos, max_dim=self.dim) if self.do_rotation: x, y, z = unrotate_mesh(self.dim, self.angles, x, y, z) if not self.is_isotropic: y, z = make_isotropic(self.dim, self.anis, y, z) return np.linalg.norm((x, y, z)[:self.dim], axis=0)
def eval_func(func, pos, mesh_type="structured"): """ Evaluate a function on a mesh. Parameters ---------- func : :any:`callable` The function to be called. Should have the signiture f(x, [y, z]) pos : :class:`list` the position tuple, containing main direction and transversal directions (x, [y, z]) mesh_type : :class:`str`, optional 'structured' / 'unstructured' Returns ------- :class:`numpy.ndarray` Function values at the given points. """ x, y, z, dim = pos2xyz(pos, calc_dim=True) if mesh_type == "structured": x, y, z, axis_lens = reshape_axis_from_struct_to_unstruct(dim, x, y, z) res = func(*[x, y, z][:dim]) if mesh_type == "structured": res = reshape_field_from_unstruct_to_struct(dim, res, axis_lens) return res
def vario_estimate_unstructured(pos, field, bin_edges, sampling_size=None, sampling_seed=None): r""" Estimates the variogram on a unstructured grid. The algorithm calculates following equation: .. math:: \gamma(r_k) = \frac{1}{2 N} \sum_{i=1}^N (z(\mathbf x_i) - z(\mathbf x_i'))^2, \; \mathrm{ with} r_k \leq \| \mathbf x_i - \mathbf x_i' \| < r_{k+1} Notes ----- Internally uses double precision and also returns doubles. Parameters ---------- pos : :class:`list` the position tuple, containing main direction and transversal directions field : :class:`numpy.ndarray` the spatially distributed data bin_edges : :class:`numpy.ndarray` the bins on which the variogram will be calculated sampling_size : :class:`int` or :any:`None`, optional for large input data, this method can take a long time to compute the variogram, therefore this argument specifies the number of data points to sample randomly Default: :any:`None` sampling_seed : :class:`int` or :any:`None`, optional seed for samples if sampling_size is given. Default: :any:`None` Returns ------- :class:`tuple` of :class:`numpy.ndarray` the estimated variogram and the bin centers """ # TODO check_mesh field = np.array(field, ndmin=1, dtype=np.double) bin_edges = np.array(bin_edges, ndmin=1, dtype=np.double) x, y, z, dim = pos2xyz(pos, calc_dim=True, dtype=np.double) bin_centres = (bin_edges[:-1] + bin_edges[1:]) / 2.0 if sampling_size is not None and sampling_size < len(field): sampled_idx = np.random.RandomState(sampling_seed).choice( np.arange(len(field)), sampling_size, replace=False) field = field[sampled_idx] x = x[sampled_idx] if dim > 1: y = y[sampled_idx] if dim > 2: z = z[sampled_idx] return bin_centres, unstructured(field, bin_edges, x, y, z)
def vtk_export_unstructured(filename, pos, field, fieldname="field"): """Export a field to vtk structured rectilinear grid file Parameters ---------- filename : :class:`str` Filename of the file to be saved, including the path. Note that an ending (\*.vtr or \*.vtu) will be added to the name. pos : :class:`list` the position tuple, containing main direction and transversal directions field : :class:`numpy.ndarray` Unstructured field to be saved. As returned by SRF. fieldname : :class:`str`, optional Name of the field in the VTK file. Default: "field" """ x, y, z = pos2xyz(pos) if y is None: y = np.zeros_like(x) if z is None: z = np.zeros_like(x) field = np.array(field).reshape(-1) if len(field) != len(x) or len(field) != len(y) or len(field) != len(z): raise ValueError("gstools.vtk_export_unstructured: " + "field shape doesn't match the given mesh") pointsToVTK(filename, x, y, z, data={fieldname: field})
def set_condition(cond_pos, cond_val, max_dim=3): """Set the conditions for kriging. Parameters ---------- cond_pos : :class:`list` the position tuple of the conditions (x, [y, z]) cond_val : :class:`numpy.ndarray` the values of the conditions max_dim : :class:`int`, optional Cut of information above the given dimension. Default: 3 Returns ------- cond_pos : :class:`list` the error checked cond_pos cond_val : :class:`numpy.ndarray` the error checked cond_val """ # convert the input for right shapes and dimension checks c_x, c_y, c_z = pos2xyz(cond_pos, dtype=np.double, max_dim=max_dim) cond_pos = xyz2pos(c_x, c_y, c_z) cond_val = np.array(cond_val, dtype=np.double).reshape(-1) if not all([len(cond_pos[i]) == len(cond_val) for i in range(max_dim)]): raise ValueError( "Please check your 'cond_pos' and 'cond_val' parameters. " + "The shapes do not match.") return cond_pos, cond_val
def vtk_export_structured( filename, pos, field, fieldname="field" ): # pragma: no cover """Export a field to vtk structured rectilinear grid file. Parameters ---------- filename : :class:`str` Filename of the file to be saved, including the path. Note that an ending (.vtr or .vtu) will be added to the name. pos : :class:`list` the position tuple, containing main direction and transversal directions field : :class:`numpy.ndarray` Structured field to be saved. As returned by SRF. fieldname : :class:`str`, optional Name of the field in the VTK file. Default: "field" """ x, y, z = pos2xyz(pos) if y is None: y = np.array([0]) if z is None: z = np.array([0]) # need fortran order in VTK field = field.reshape(-1, order="F") if len(field) != len(x) * len(y) * len(z): raise ValueError( "gstools.vtk_export_structured: " + "field shape doesn't match the given mesh" ) gridToVTK(filename, x, y, z, pointData={fieldname: field})
def _pre_pos(self, pos, mesh_type="unstructured", make_unstruct=False): """ Preprocessing positions and mesh_type. Parameters ---------- pos : :any:`iterable` the position tuple, containing main direction and transversal directions mesh_type : :class:`str` 'structured' / 'unstructured' make_unstruct: :class:`bool` State if mesh_type should be made unstructured. Returns ------- x : :class:`numpy.ndarray` first components of unrotated and isotropic position vectors y : :class:`numpy.ndarray` or None analog to x z : :class:`numpy.ndarray` or None analog to x pos : :class:`tuple` of :class:`numpy.ndarray` the normalized position tuple mesh_type_gen : :class:`str` 'structured' / 'unstructured' for the generator mesh_type_changed : :class:`bool` State if the mesh_type was changed. axis_lens : :class:`tuple` or :any:`None` axis lengths of the structured mesh if mesh type was changed. """ x, y, z = pos2xyz(pos, max_dim=self.model.dim) pos = xyz2pos(x, y, z) mesh_type_gen = mesh_type # format the positional arguments of the mesh check_mesh(self.model.dim, x, y, z, mesh_type) mesh_type_changed = False axis_lens = None if (self.model.do_rotation or make_unstruct) and mesh_type == "structured": mesh_type_changed = True mesh_type_gen = "unstructured" x, y, z, axis_lens = reshape_axis_from_struct_to_unstruct( self.model.dim, x, y, z) if self.model.do_rotation: x, y, z = unrotate_mesh(self.model.dim, self.model.angles, x, y, z) if not self.model.is_isotropic: y, z = make_isotropic(self.model.dim, self.model.anis, y, z) return x, y, z, pos, mesh_type_gen, mesh_type_changed, axis_lens
def set_condition(self, cond_pos, cond_val): """Set the conditions for kriging. Parameters ---------- cond_pos : :class:`list` the position tuple of the conditions (x, [y, z]) cond_val : :class:`numpy.ndarray` the values of the conditions """ self._c_x, self._c_y, self._c_z = pos2xyz( cond_pos, dtype=np.double, max_dim=self.model.dim ) self._cond_pos = xyz2pos(self._c_x, self._c_y, self._c_z) self._cond_val = np.array(cond_val, dtype=np.double).reshape(-1)
def _vtk_unstructured_helper(pos, fields): if not isinstance(fields, dict): fields = {"field": fields} x, y, z = pos2xyz(pos) if y is None: y = np.zeros_like(x) if z is None: z = np.zeros_like(x) for field in fields: fields[field] = fields[field].reshape(-1) if (len(fields[field]) != len(x) or len(fields[field]) != len(y) or len(fields[field]) != len(z)): raise ValueError("gstools.vtk_export_unstructured: " "field shape doesn't match the given mesh") return x, y, z, fields
def _vtk_structured_helper(pos, fields): """An internal helper to extract what is needed for the vtk rectilinear grid """ if not isinstance(fields, dict): fields = {"field": fields} x, y, z = pos2xyz(pos) if y is None: y = np.array([0]) if z is None: z = np.array([0]) # need fortran order in VTK for field in fields: fields[field] = fields[field].reshape(-1, order="F") if len(fields[field]) != len(x) * len(y) * len(z): raise ValueError("gstools.vtk_export_structured: " "field shape doesn't match the given mesh") return x, y, z, fields
def simple(srf): """Condition a given spatial random field with simple kriging. Parameters ---------- srf : :any:`SRF` The spatial random field class containing all information Returns ------- cond_field : :class:`numpy.ndarray` the conditioned field krige_field : :class:`numpy.ndarray` the kriged field err_field : :class:`numpy.ndarray` the error field to set the given random field to zero at the conditions krige_var : :class:`numpy.ndarray` the variance of the kriged field """ if srf._value_type != "scalar": raise ValueError("Conditioned SRF: only scalar fields allowed.") krige_sk = Simple( model=srf.model, mean=srf.mean, cond_pos=srf.cond_pos, cond_val=srf.cond_val, ) krige_field, krige_var = krige_sk(srf.pos, srf.mesh_type) # evaluate the field at the conditional points x, y, z = pos2xyz(srf.cond_pos, max_dim=srf.model.dim) if srf.model.do_rotation: x, y, z = unrotate_mesh(srf.model.dim, srf.model.angles, x, y, z) y, z = make_isotropic(srf.model.dim, srf.model.anis, y, z) err_data = srf.generator.__call__(x, y, z, "unstructured") + srf.mean err_sk = Simple( model=srf.model, mean=srf.mean, cond_pos=srf.cond_pos, cond_val=err_data, ) err_field, __ = err_sk(srf.pos, srf.mesh_type) cond_field = srf.raw_field + krige_field - err_field + srf.mean info = {} return cond_field, krige_field, err_field, krige_var, info
def ordinary(srf): """Condition a given spatial random field with ordinary kriging. Parameters ---------- srf : :any:`SRF` The spatial random field class containing all information Returns ------- cond_field : :class:`numpy.ndarray` the conditioned field krige_field : :class:`numpy.ndarray` the kriged field err_field : :class:`numpy.ndarray` the error field to set the given random field to zero at the conditions krige_var : :class:`numpy.ndarray` the variance of the kriged field """ krige_ok = Ordinary(model=srf.model, cond_pos=srf.cond_pos, cond_val=srf.cond_val) krige_field, krige_var = krige_ok(srf.pos, srf.mesh_type) # evaluate the field at the conditional points x, y, z = pos2xyz(srf.cond_pos, max_dim=srf.model.dim) if srf.model.do_rotation: x, y, z = unrotate_mesh(srf.model.dim, srf.model.angles, x, y, z) y, z = make_isotropic(srf.model.dim, srf.model.anis, y, z) err_data = srf.generator.__call__(x, y, z, "unstructured") err_ok = Ordinary(model=srf.model, cond_pos=srf.cond_pos, cond_val=err_data) err_field, __ = err_ok(srf.pos, srf.mesh_type) cond_field = srf.raw_field + krige_field - err_field info = {"mean": krige_ok.mean} return cond_field, krige_field, err_field, krige_var, info
def _get_krige_vecs(self, pos, chunk_slice=(0, None), ext_drift=None): """Calculate the RHS of the kriging equation.""" chunk_size = len(pos[0]) if chunk_slice[1] is None else chunk_slice[1] chunk_size -= chunk_slice[0] size = self.cond_no + int(self.unbiased) + self.drift_no res = np.empty((size, chunk_size), dtype=np.double) res[:self.cond_no, :] = self.model.vario_nugget( self._get_dists(self._krige_pos, pos, chunk_slice)) if self.unbiased: res[self.cond_no, :] = 1 # trend function need the anisotropic and rotated positions if not self.model.is_isotropic: x, y, z = pos2xyz(pos, max_dim=self.model.dim) y, z = make_anisotropic(self.model.dim, self.model.anis, y, z) if self.model.do_rotation: x, y, z = rotate_mesh(self.model.dim, self.model.angles, x, y, z) pos = xyz2pos(x, y, z, max_dim=self.model.dim) chunk_pos = list(pos[:self.model.dim]) for i in range(self.model.dim): chunk_pos[i] = chunk_pos[i][slice(*chunk_slice)] for i, f in enumerate(self.drift_functions): res[-self.drift_no + i, :] = f(*chunk_pos) return res
def __call__( self, pos, seed=np.nan, point_volumes=0.0, mesh_type="unstructured" ): """Generate the spatial random field. The field is saved as `self.field` and is also returned. Parameters ---------- pos : :class:`list` the position tuple, containing main direction and transversal directions seed : :class:`int`, optional seed for RNG for reseting. Default: keep seed from generator point_volumes : :class:`float` or :class:`numpy.ndarray` If your evaluation points for the field are coming from a mesh, they are probably representing a certain element volume. This volume can be passed by `point_volumes` to apply the given variance upscaling. If `point_volumes` is ``0`` nothing is changed. Default: ``0`` mesh_type : :class:`str` 'structured' / 'unstructured' Returns ------- field : :class:`numpy.ndarray` the SRF """ # internal conversation x, y, z = pos2xyz(pos, max_dim=self.model.dim) self.pos = xyz2pos(x, y, z) self.mesh_type = mesh_type # update the model/seed in the generator if any changes were made self.generator.update(self.model, seed) # format the positional arguments of the mesh check_mesh(self.model.dim, x, y, z, mesh_type) mesh_type_changed = False if self.model.do_rotation: if mesh_type == "structured": mesh_type_changed = True mesh_type_old = mesh_type mesh_type = "unstructured" x, y, z, axis_lens = reshape_axis_from_struct_to_unstruct( self.model.dim, x, y, z ) x, y, z = unrotate_mesh(self.model.dim, self.model.angles, x, y, z) y, z = make_isotropic(self.model.dim, self.model.anis, y, z) # generate the field self.raw_field = self.generator.__call__(x, y, z, mesh_type) # reshape field if we got an unstructured mesh if mesh_type_changed: mesh_type = mesh_type_old self.raw_field = reshape_field_from_unstruct_to_struct( self.model.dim, self.raw_field, axis_lens ) # apply given conditions to the field if self.condition: ( cond_field, krige_field, err_field, krigevar, info, ) = self.cond_func(self) # store everything in the class self.field = cond_field self.krige_field = krige_field self.err_field = err_field self.krige_var = krigevar if "mean" in info: # ordinary krging estimates mean self.mean = info["mean"] else: self.field = self.raw_field + self.mean # upscaled variance if not np.isscalar(point_volumes) or not np.isclose(point_volumes, 0): scaled_var = self.upscaling_func(self.model, point_volumes) self.field -= self.mean self.field *= np.sqrt(scaled_var / self.model.sill) self.field += self.mean return self.field
def __call__(self, pos, mesh_type="unstructured"): """ Generate the ordinary kriging field. The field is saved as `self.field` and is also returned. Parameters ---------- pos : :class:`list` the position tuple, containing main direction and transversal directions (x, [y, z]) mesh_type : :class:`str` 'structured' / 'unstructured' Returns ------- field : :class:`numpy.ndarray` the kriged field krige_var : :class:`numpy.ndarray` the kriging error variance """ # internal conversation x, y, z = pos2xyz(pos, dtype=np.double, max_dim=self.model.dim) c_x, c_y, c_z = pos2xyz(self.cond_pos, dtype=np.double, max_dim=self.model.dim) self.pos = xyz2pos(x, y, z) self.mesh_type = mesh_type # format the positional arguments of the mesh check_mesh(self.model.dim, x, y, z, mesh_type) mesh_type_changed = False if mesh_type == "structured": mesh_type_changed = True mesh_type_old = mesh_type mesh_type = "unstructured" x, y, z, axis_lens = reshape_axis_from_struct_to_unstruct( self.model.dim, x, y, z) if self.model.do_rotation: x, y, z = unrotate_mesh(self.model.dim, self.model.angles, x, y, z) c_x, c_y, c_z = unrotate_mesh(self.model.dim, self.model.angles, c_x, c_y, c_z) y, z = make_isotropic(self.model.dim, self.model.anis, y, z) c_y, c_z = make_isotropic(self.model.dim, self.model.anis, c_y, c_z) # set condtions cond = np.concatenate((self.cond_val, [0])) krig_mat = inv(self._get_krig_mat((c_x, c_y, c_z), (c_x, c_y, c_z))) krig_vecs = self._get_vario_mat((c_x, c_y, c_z), (x, y, z), add=True) # generate the kriged field field, krige_var = krigesum(krig_mat, krig_vecs, cond) # calculate the estimated mean (kriging field at infinity) mean_est = np.concatenate((np.full_like(self.cond_val, self.model.sill), [1])) self.mean = np.einsum("i,ij,j", cond, krig_mat, mean_est) # reshape field if we got an unstructured mesh if mesh_type_changed: mesh_type = mesh_type_old field = reshape_field_from_unstruct_to_struct( self.model.dim, field, axis_lens) krige_var = reshape_field_from_unstruct_to_struct( self.model.dim, krige_var, axis_lens) # save the field self.krige_var = krige_var self.field = field return self.field, self.krige_var
def __call__( self, pos, seed=np.nan, force_moments=False, point_volumes=0.0, mesh_type="unstructured", ): """Generate the spatial random field. Parameters ---------- pos : :class:`list` the position tuple, containing main direction and transversal directions seed : :class:`int`, optional seed for RNG for reseting. Default: keep seed from generator force_moments : :class:`bool` Force the generator to exactly match mean and variance. Default: ``False`` point_volumes : :class:`float` or :class:`numpy.ndarray` If your evaluation points for the field are coming from a mesh, they are probably representing a certain element volume. This volumes can be passed by `point_volumes` to apply the given variance upscaling. If `point_volumes` is ``0`` nothing is changed. Default: ``0`` mesh_type : :class:`str` 'structured' / 'unstructured' Returns ------- field : :class:`numpy.ndarray` the SRF """ # internal conversation x, y, z = pos2xyz(pos) # update the model/seed in the generator if any changes were made self.generator.update(self.model, seed) # format the positional arguments of the mesh check_mesh(self.model.dim, x, y, z, mesh_type) mesh_type_changed = False if self.do_rotation: if mesh_type == "structured": mesh_type_changed = True mesh_type_old = mesh_type mesh_type = "unstructured" x, y, z, axis_lens = reshape_axis_from_struct_to_unstruct( self.model.dim, x, y, z) x, y, z = unrotate_mesh(self.model.dim, self.model.angles, x, y, z) y, z = make_isotropic(self.model.dim, self.model.anis, y, z) x, y, z = reshape_input(x, y, z, mesh_type) # generate the field field = self.generator.__call__(x, y, z) # reshape field if we got an unstructured mesh if mesh_type_changed: mesh_type = mesh_type_old field = reshape_field_from_unstruct_to_struct( self.model.dim, field, axis_lens) # force variance and mean to be exactly as given (if wanted) if force_moments: var_in = np.var(field) mean_in = np.mean(field) rescale = np.sqrt(self.model.sill / var_in) field = rescale * (field - mean_in) # upscaled variance scaled_var = self.upscaling_func(self.model, point_volumes) # rescale and shift the field to the mean self.field = np.sqrt(scaled_var / self.model.sill) * field + self.mean return self.field
def vario_estimate_unstructured( pos, field, bin_edges, sampling_size=None, sampling_seed=None, estimator="matheron", ): r""" Estimates the variogram on a unstructured grid. The algorithm calculates following equation: .. math:: \gamma(r_k) = \frac{1}{2 N(r_k)} \sum_{i=1}^{N(r_k)} (z(\mathbf x_i) - z(\mathbf x_i'))^2 \; , with :math:`r_k \leq \| \mathbf x_i - \mathbf x_i' \| < r_{k+1}` being the bins. Or if the estimator "cressie" was chosen: .. math:: \gamma(r_k) = \frac{\left(\frac{1}{N(r_k)} \sum_{i=1}^{N(r_k)} \left|z(\mathbf x_i) - z(\mathbf x_i')\right|^{0.5}\right)^4} {0.457 + 0.494 / N(r_k) + 0.045 / N^2(r_k)} \; , with :math:`r_k \leq \| \mathbf x_i - \mathbf x_i' \| < r_{k+1}` being the bins. The Cressie estimator is more robust to outliers. Notes ----- Internally uses double precision and also returns doubles. Parameters ---------- pos : :class:`list` the position tuple, containing main direction and transversal directions field : :class:`numpy.ndarray` the spatially distributed data bin_edges : :class:`numpy.ndarray` the bins on which the variogram will be calculated sampling_size : :class:`int` or :any:`None`, optional for large input data, this method can take a long time to compute the variogram, therefore this argument specifies the number of data points to sample randomly Default: :any:`None` sampling_seed : :class:`int` or :any:`None`, optional seed for samples if sampling_size is given. Default: :any:`None` estimator : :class:`str`, optional the estimator function, possible choices: * "matheron": the standard method of moments of Matheron * "cressie": an estimator more robust to outliers Default: "matheron" Returns ------- :class:`tuple` of :class:`numpy.ndarray` the estimated variogram and the bin centers """ # TODO check_mesh field = np.array(field, ndmin=1, dtype=np.double) bin_edges = np.array(bin_edges, ndmin=1, dtype=np.double) x, y, z, dim = pos2xyz(pos, calc_dim=True, dtype=np.double) bin_centres = (bin_edges[:-1] + bin_edges[1:]) / 2.0 if sampling_size is not None and sampling_size < len(field): sampled_idx = np.random.RandomState(sampling_seed).choice( np.arange(len(field)), sampling_size, replace=False) field = field[sampled_idx] x = x[sampled_idx] if dim > 1: y = y[sampled_idx] if dim > 2: z = z[sampled_idx] cython_estimator = _set_estimator(estimator) return ( bin_centres, unstructured(field, bin_edges, x, y, z, estimator_type=cython_estimator), )
def __call__(self, pos, mesh_type="unstructured"): """ Generate the simple kriging field. The field is saved as `self.field` and is also returned. Parameters ---------- pos : :class:`list` the position tuple, containing main direction and transversal directions (x, [y, z]) mesh_type : :class:`str` 'structured' / 'unstructured' Returns ------- field : :class:`numpy.ndarray` the kriged field krige_var : :class:`numpy.ndarray` the kriging error variance """ # internal conversation x, y, z = pos2xyz(pos, dtype=np.double, max_dim=self.model.dim) c_x, c_y, c_z = pos2xyz(self.cond_pos, dtype=np.double, max_dim=self.model.dim) self.pos = xyz2pos(x, y, z) self.mesh_type = mesh_type # format the positional arguments of the mesh check_mesh(self.model.dim, x, y, z, mesh_type) mesh_type_changed = False if mesh_type == "structured": mesh_type_changed = True mesh_type_old = mesh_type mesh_type = "unstructured" x, y, z, axis_lens = reshape_axis_from_struct_to_unstruct( self.model.dim, x, y, z) if self.model.do_rotation: x, y, z = unrotate_mesh(self.model.dim, self.model.angles, x, y, z) c_x, c_y, c_z = unrotate_mesh(self.model.dim, self.model.angles, c_x, c_y, c_z) y, z = make_isotropic(self.model.dim, self.model.anis, y, z) c_y, c_z = make_isotropic(self.model.dim, self.model.anis, c_y, c_z) # set condtions to zero mean cond = self.cond_val - self.mean krig_mat = inv(self._get_cov_mat((c_x, c_y, c_z), (c_x, c_y, c_z))) krig_vecs = self._get_cov_mat((c_x, c_y, c_z), (x, y, z)) # generate the kriged field field, krige_var = krigesum(krig_mat, krig_vecs, cond) # reshape field if we got an unstructured mesh if mesh_type_changed: mesh_type = mesh_type_old field = reshape_field_from_unstruct_to_struct( self.model.dim, field, axis_lens) krige_var = reshape_field_from_unstruct_to_struct( self.model.dim, krige_var, axis_lens) # calculate the kriging error self.krige_var = self.model.sill - krige_var # add the given mean self.field = field + self.mean return self.field, self.krige_var