Declustering
The declustering task computes spatial declustering weights for a set of sample locations by measuring each sample's influence on a regular evaluation grid. Samples in dense clusters receive lower weights; isolated samples receive higher weights. The resulting weights sum to 1 and can be used to compute unbiased statistics from irregularly sampled data.
How it works
For each sample, an indicator vector is constructed (1 at that sample's position, 0 elsewhere) and estimated onto every grid point using a spatial estimator. The sum of those estimates across the grid measures how much "territory" the sample represents. Weights are then normalised so they sum to 1:
The choice of estimator is controlled by the optional power parameter:
| Mode | power | Estimator | Behaviour |
|---|---|---|---|
| KNN | null | Arithmetic mean of nearest neighbors | All neighbors contribute equally |
| IDW | positive float (e.g. 2.0) | Inverse-distance weighted mean | Closer neighbors contribute more |
Parameters
source(object)object— URL of a pointset or downhole-intervals object containing the sample locations to decluster.
grid(object)object— URL of a pointset, regular-3d-grid, or regular-masked-3d-grid object. This is the evaluation grid used to measure each sample's spatial influence. A denser, more uniform grid produces more stable weights.
target(object)object— URL of the object to write the declustering weight attribute onto. Typically the same assource.attribute— An attribute specification (create or update) defining where to store the computed weights.
neighborhood(object)- Controls the search ellipsoid and sample limits used by the estimator.
-
{
"ellipsoid": {
"ellipsoid_ranges": {
"major": 100.0, // Major axis length (longest search range).
"semi_major": 100.0,
"minor": 25.0 // Minor axis length (shortest search range).
},
"rotation": {
"dip_azimuth": 0.0,
"dip": 0.0,
"pitch": 0.0
}
},
"max_samples": 20, // Maximum number of neighbors to use per grid point.
"min_samples": 1 // Minimum required; grid points with fewer are skipped.
} - Optional per-octant / per-drillhole constraints (
max_empty_octants,max_samples_per_octant,max_samples_per_drillhole,max_drillholes_per_estimate,max_empty_quadrants,max_samples_per_quadrant) are also supported.
power(float, optional, default2.0)- When omitted, defaults to
2.0— the task runs in IDW mode with inverse-distance-squared weighting. - When set to a positive value (e.g.
2.0), the task runs in IDW mode — nearer neighbors receive higher weight proportional to . - When explicitly set to
null, the task runs in KNN mode — all neighbors within the ellipsoid contribute equally. - Common values:
1.0(linear decay),2.0(inverse-square, standard choice),4.0(high contrast).
- When omitted, defaults to
Examples
For more information, see the declustering API reference.
KNN mode (power = null)
requests.post(
"https://{hub}.api.seequent.com/compute/orgs/{org_id}/geostatistics/declustering",
headers={"Authorization": "Bearer {token}"},
json={
"parameters": {
"source": {
"object": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-drillholes.json"
},
"grid": {
"object": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-grid.json"
},
"target": {
"object": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-drillholes.json",
"attribute": {"operation": "create", "name": "declustering_weights"}
},
"neighborhood": {
"ellipsoid": {
"ellipsoid_ranges": {"major": 100.0, "semi_major": 100.0, "minor": 25.0},
"rotation": {"dip_azimuth": 0.0, "dip": 0.0, "pitch": 0.0}
},
"max_samples": 20,
"min_samples": 1
},
"power": null
}
},
)
IDW mode (power = 2.0)
requests.post(
"https://{hub}.api.seequent.com/compute/orgs/{org_id}/geostatistics/declustering",
headers={"Authorization": "Bearer {token}"},
json={
"parameters": {
"source": {
"object": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-drillholes.json"
},
"grid": {
"object": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-grid.json"
},
"target": {
"object": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-drillholes.json",
"attribute": {"operation": "create", "name": "declustering_weights"}
},
"neighborhood": {
"ellipsoid": {
"ellipsoid_ranges": {"major": 100.0, "semi_major": 100.0, "minor": 25.0},
"rotation": {"dip_azimuth": 0.0, "dip": 0.0, "pitch": 0.0}
},
"max_samples": 20,
"min_samples": 1
},
"power": 2.0
}
},
)
Result
{
"message": "Declustering completed (IDW, power=2.0).",
"target": {
"reference": "https://{hub}.api.seequent.com/geoscience-object/orgs/{org_id}/workspaces/{workspace_id}/objects/path/my-drillholes.json",
"attribute": {
"reference": "locations.attributes[?name=='declustering_weights']",
"name": "declustering_weights"
}
}
}
For KNN mode the message will read "Declustering completed (KNN).".
Tips
- The
sourceandtargetcan reference the same object. - Use a uniform, regular grid that covers the full extent of your samples. A grid with at least 10× more points than samples produces stable weights.
- Set the ellipsoid large enough that every grid point can find at least
min_samplesneighbors. If the task raises an error about zero weights, enlarge the ellipsoid or reducemin_samples. - KNN is the default and works well for most datasets. Use IDW (with
power ≥ 2.0) when your data has sharp density contrasts and you want stronger differentiation between clustered and isolated samples. - Higher power values increase the weight contrast between clustered and isolated samples but can produce unstable results if samples are very close together.