Skip to content

Commit ea1c54d

Browse files
committed
some updates
1 parent 77a6765 commit ea1c54d

7 files changed

Lines changed: 36 additions & 27 deletions

File tree

‎Cargo.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rust_conn"
3-
version = "0.2.2"
3+
version = "0.2.3"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

‎NEWS.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Version 0.2.3
2+
* Fixed the isolated pixel calculations by duplicating its values to a fake neighbour.
3+
* Increased the capacity of graph to take more neighbours for high resoltion rasters.
4+
* Changed the default of `sigma` paramter to 1.
5+
16
# Version 0.2.2
27
* Removed the dependency on GDAL, replacing it with `rasterio`.
38
* Updated logic to ignore overview level 1 (both when reading and generating) since it corresponds to the original resolution and requires no additional computation.
@@ -7,3 +12,11 @@
712
* Added Euclidean and Haversine distances for projected and unprojected grids, respectively, instead of using cell units.
813
* Some changes in the arguments names including `max_cost`, `window_size` and `outer_window`.
914
* Some small fixes for graph calculation.
15+
16+
# Version 0.2.0
17+
Added geographic distance (in km) instead of cell units
18+
Replaced the scale argument with max_cost
19+
Various minor improvements
20+
21+
# Version 0.1.0
22+
* Initial version.

‎connectivity/core.py‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def connectedness(
1313
window_size=3,
1414
outer_window=9,
1515
levels=[2, 4, 8, 16],
16-
sigma=None,
16+
sigma=1,
1717
option=3,
1818
n_threads=None,
1919
filename=""
@@ -62,7 +62,7 @@ def connectedness(
6262
Default is [2, 4, 8, 16].
6363
sigma : float, optional
6464
Standard deviation of the Gaussian kernel used for smoothing.
65-
Default is None (smoothing disabled).
65+
Default is 1. Zero or None for disabling smoothing.
6666
option : int, optional
6767
Option flag to generate the connected condition from connectedness and input condition.
6868
Default is 3:
@@ -92,7 +92,7 @@ def connectedness(
9292
print(f"Notice: 'outer_window' was smaller than 'window_size' and has been adjusted to {window_size}.")
9393
outer_window = window_size
9494

95-
# Read raster overviews as a dictionary
95+
# Read raster overviews as a dictionary; this checks levels as well
9696
data_dict, tran_dict, is_geo = read_raster(file=condition_file, gdf=polygon_mask, levels=levels, expand_px=outer_window)
9797

9898
conn_array = connectivity(
@@ -108,7 +108,7 @@ def connectedness(
108108
)
109109

110110
# Smooth the output array with Gaussian filtering
111-
if sigma is not None:
111+
if sigma is not None and sigma != 0:
112112
sigma = max(sigma, 1)
113113
conn_array = smoothing_filter(conn_array, sigma=sigma)
114114

@@ -132,7 +132,7 @@ def beri(
132132
window_size=3,
133133
outer_window=9,
134134
levels=[2, 4, 8, 16],
135-
sigma=None,
135+
sigma=1,
136136
n_threads=None,
137137
filename=""
138138
):
@@ -187,7 +187,7 @@ def beri(
187187
Default is [2, 4, 8, 16].
188188
sigma : float, optional
189189
Standard deviation for the Gaussian kernel if smoothing is applied to input layers.
190-
Default is None (no smoothing).
190+
Default is 1. Zero or None for disabling smoothing.
191191
n_threads : int, optional
192192
The number of CPU cores for parallel processing.
193193
Default is None (all available cores).
@@ -212,7 +212,7 @@ def beri(
212212
print(f"Notice: 'outer_window' was smaller than 'window_size' and has been adjusted to {window_size}.")
213213
outer_window = window_size
214214

215-
# Read raster overview as a dictionary
215+
# Read raster overview as a dictionary; this checks levels as well.
216216
data_dict, tran_dict, is_geo = read_raster(file=condition_file, gdf=polygon_mask, levels=levels, expand_px=outer_window)
217217

218218
# Insert current climate as the first element in the list (this is important) before reading
@@ -240,7 +240,7 @@ def beri(
240240
)
241241

242242
# Smooth the output array with Gaussian filtering
243-
if sigma is not None:
243+
if sigma is not None and sigma != 0:
244244
out_array = smoothing_filter(out_array, sigma=sigma)
245245

246246
if len(filename) > 3:

‎connectivity/rastio.py‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ def create_overviews(input_raster, output_raster=None, overview_levels=[2, 4, 8,
6363
print(f"Error creating overviews: {e}")
6464

6565

66-
6766
def overview_info(file_path):
6867
"""Display information about all available overviews and their actual dimensions.
6968
@@ -94,7 +93,6 @@ def overview_info(file_path):
9493
print(f" Level {level}: {w} x {h}")
9594

9695

97-
9896
def read_raster(file, gdf=None, levels=None, expand_px=3):
9997
"""Reads specified overview levels from a multi-band Cloud-Optimized GeoTIFF (COG) file
10098
and stores them in a dictionary.
@@ -223,7 +221,6 @@ def read_raster(file, gdf=None, levels=None, expand_px=3):
223221
return data_dict, tran_dict, is_geo
224222

225223

226-
227224
def write_raster(in_array, outfile="output.tif", template="somefile.tif"):
228225
"""Write a numpy array to a GeoTIFF file using the geographic transformation
229226
and projection information from a template raster file.

‎src/graph.rs‎

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ pub fn multi_level_graph(
7171
}
7272
}
7373

74-
// Process points - this could be parallelized for large datasets
74+
// Process points
7575
for point_idx in 0..num_points {
7676
let i = i_array[point_idx];
7777
let j = j_array[point_idx];
7878
let u = point_idx as u16 + level as u16 * 100;
7979

8080
// Process neighbors at current level
81-
process_current_level_neighbors(
81+
current_level_neighbors(
8282
i, j, u,
8383
&COLS, &ROWS,
8484
&node_mapping,
@@ -90,7 +90,7 @@ pub fn multi_level_graph(
9090

9191
// Process connections to higher level if needed
9292
if level < max_level && edge_indices.contains(&(i, j)) {
93-
process_higher_level_connections(
93+
higher_level_connections(
9494
i, j,
9595
&node_mapping,
9696
&node_mapping_higher,
@@ -108,7 +108,7 @@ pub fn multi_level_graph(
108108
}
109109

110110

111-
/// Create node mapping efficiently
111+
/// Create node mapping (the unique ID of each node)
112112
fn create_node_mapping(
113113
i_array: &[i32],
114114
j_array: &[i32],
@@ -136,11 +136,10 @@ fn create_node_mapping(
136136
/// output graph: (u, v) (adj_cond, cond, dist, similarities)
137137
/// u: source, v: destination
138138
#[inline]
139-
fn process_current_level_neighbors(
139+
fn current_level_neighbors(
140140
i: i32,
141141
j: i32,
142-
u: u16,
143-
// level: i32,
142+
u: u16, // source node
144143
i_ngb: &[i32],
145144
j_ngb: &[i32],
146145
node_mapping: &HashMap<(i32, i32), (u16, f32, Vec<f32>)>,
@@ -170,11 +169,11 @@ fn process_current_level_neighbors(
170169
}
171170

172171

173-
/// Process connections to higher level
172+
/// Process connections to higher level (e.g. level 2 to level 4)
174173
/// output graph: (u, v) (adj_cond, cond, dist, similarities)
175174
/// u: source, v: destination
176175
#[inline]
177-
fn process_higher_level_connections(
176+
fn higher_level_connections(
178177
i: i32, j: i32,
179178
node_mapping: &HashMap<(i32, i32), (u16, f32, Vec<f32>)>,
180179
node_mapping_higher: &HashMap<(i32, i32), (u16, f32, Vec<f32>)>,
@@ -188,7 +187,7 @@ fn process_higher_level_connections(
188187
let higher_level: i32 = level * 2;
189188

190189
// Get all higher neighbors at once
191-
let higher_neighbors = get_higher_neighbors(i, j);
190+
let higher_neighbors = get_edge_neighbors(i, j);
192191

193192
// Get the Affines for distance calc
194193
let transform: &Affine = transforms.get(&level).unwrap();
@@ -214,9 +213,9 @@ fn process_higher_level_connections(
214213
}
215214

216215

217-
/// Get the 3 possible neighbours in the higher level
216+
/// Get the 3 possible neighbours of edge cells in the higher level
218217
/// i.e. the link between a level edge to its higher level cells
219-
fn get_higher_neighbors(i: i32, j: i32) -> [(i32, i32); 3] {
218+
fn get_edge_neighbors(i: i32, j: i32) -> [(i32, i32); 3] {
220219
// Higher level cell containing the target cell
221220
let target_higher = (i >> 1, j >> 1);
222221
// 8 neighbor offsets: N, S, W, E, NW, NE, SW, SE
@@ -259,7 +258,7 @@ fn get_higher_neighbors(i: i32, j: i32) -> [(i32, i32); 3] {
259258
}
260259

261260

262-
/// Get edge cells efficiently using HashSet
261+
/// Efficiently get edge cells in a level neighbourhood using HashSet
263262
fn get_edge_indices(i_arr: &[i32], j_arr: &[i32]) -> HashSet<(i32, i32)> {
264263
let i_min = *i_arr.iter().min().unwrap_or(&0);
265264
let i_max = *i_arr.iter().max().unwrap_or(&0);

‎src/window.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn multi_level_window(
8787
(current_height / agg_factor, current_width / agg_factor)
8888
};
8989

90-
// Iterate over the NxN neighborhood
90+
// Iterate over the NxN neighborhood (this is in potential higher level)
9191
for di in -radius..=radius {
9292
for dj in -radius..=radius {
9393
let higher_i = higher_center_i + di;

0 commit comments

Comments
 (0)